diff --git a/.gitignore b/.gitignore index 3c4efe20..7d565848 100644 --- a/.gitignore +++ b/.gitignore @@ -258,4 +258,7 @@ paket-files/ # Python Tools for Visual Studio (PTVS) __pycache__/ -*.pyc \ No newline at end of file +*.pyc + +build/ +dist/ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..31ee66bd --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "jslib"] + path = jslib + url = https://github.com/bitwarden/jslib.git + branch = master diff --git a/bitwarden-dc.sln b/bitwarden-dc.sln deleted file mode 100644 index cc22ec88..00000000 --- a/bitwarden-dc.sln +++ /dev/null @@ -1,38 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{E24C65DC-7377-472B-9ABA-BC803B73C61A}") = "bitwarden-dc", ".", "{A4DE5293-DB47-41D1-8890-7C67B83F663C}" - ProjectSection(WebsiteProperties) = preProject - TargetFrameworkMoniker = ".NETFramework,Version%3Dv4.0" - Debug.AspNetCompiler.VirtualPath = "/localhost_4405" - Debug.AspNetCompiler.PhysicalPath = "." - Debug.AspNetCompiler.TargetPath = "PrecompiledWeb\localhost_4405\" - Debug.AspNetCompiler.Updateable = "true" - Debug.AspNetCompiler.ForceOverwrite = "true" - Debug.AspNetCompiler.FixedNames = "false" - Debug.AspNetCompiler.Debug = "True" - Release.AspNetCompiler.VirtualPath = "/localhost_4405" - Release.AspNetCompiler.PhysicalPath = "." - Release.AspNetCompiler.TargetPath = "PrecompiledWeb\localhost_4405\" - Release.AspNetCompiler.Updateable = "true" - Release.AspNetCompiler.ForceOverwrite = "true" - Release.AspNetCompiler.FixedNames = "false" - Release.AspNetCompiler.Debug = "False" - VWDPort = "4405" - SlnRelativePath = "." - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {A4DE5293-DB47-41D1-8890-7C67B83F663C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A4DE5293-DB47-41D1-8890-7C67B83F663C}.Debug|Any CPU.Build.0 = Debug|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/bitwarden-directory-connector-noinstaller.sln b/bitwarden-directory-connector-noinstaller.sln deleted file mode 100644 index f708c711..00000000 --- a/bitwarden-directory-connector-noinstaller.sln +++ /dev/null @@ -1,37 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26730.10 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Console", "src\Console\Console.csproj", "{DD4E5CD2-C9DD-4912-9A25-1600A07BF8C2}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Core", "src\Core\Core.csproj", "{AE082484-A34C-4B3A-A69F-49E5EF298B27}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Service", "src\Service\Service.csproj", "{A8FD8CED-5510-4EBD-AACE-5D3CBB7516DB}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {DD4E5CD2-C9DD-4912-9A25-1600A07BF8C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DD4E5CD2-C9DD-4912-9A25-1600A07BF8C2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DD4E5CD2-C9DD-4912-9A25-1600A07BF8C2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DD4E5CD2-C9DD-4912-9A25-1600A07BF8C2}.Release|Any CPU.Build.0 = Release|Any CPU - {AE082484-A34C-4B3A-A69F-49E5EF298B27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AE082484-A34C-4B3A-A69F-49E5EF298B27}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AE082484-A34C-4B3A-A69F-49E5EF298B27}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AE082484-A34C-4B3A-A69F-49E5EF298B27}.Release|Any CPU.Build.0 = Release|Any CPU - {A8FD8CED-5510-4EBD-AACE-5D3CBB7516DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A8FD8CED-5510-4EBD-AACE-5D3CBB7516DB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A8FD8CED-5510-4EBD-AACE-5D3CBB7516DB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A8FD8CED-5510-4EBD-AACE-5D3CBB7516DB}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {52CB25C1-56A6-4FBE-977C-E842EA0AFAD7} - EndGlobalSection -EndGlobal diff --git a/bitwarden-directory-connector.sln b/bitwarden-directory-connector.sln deleted file mode 100644 index 95a9245a..00000000 --- a/bitwarden-directory-connector.sln +++ /dev/null @@ -1,41 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.27004.2009 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Console", "src\Console\Console.csproj", "{DD4E5CD2-C9DD-4912-9A25-1600A07BF8C2}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Core", "src\Core\Core.csproj", "{AE082484-A34C-4B3A-A69F-49E5EF298B27}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Service", "src\Service\Service.csproj", "{A8FD8CED-5510-4EBD-AACE-5D3CBB7516DB}" -EndProject -Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "Setup", "src\Setup\Setup.vdproj", "{4D852DF8-9327-43D0-93AB-FA68D4F3414B}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {DD4E5CD2-C9DD-4912-9A25-1600A07BF8C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DD4E5CD2-C9DD-4912-9A25-1600A07BF8C2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DD4E5CD2-C9DD-4912-9A25-1600A07BF8C2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DD4E5CD2-C9DD-4912-9A25-1600A07BF8C2}.Release|Any CPU.Build.0 = Release|Any CPU - {AE082484-A34C-4B3A-A69F-49E5EF298B27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AE082484-A34C-4B3A-A69F-49E5EF298B27}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AE082484-A34C-4B3A-A69F-49E5EF298B27}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AE082484-A34C-4B3A-A69F-49E5EF298B27}.Release|Any CPU.Build.0 = Release|Any CPU - {A8FD8CED-5510-4EBD-AACE-5D3CBB7516DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A8FD8CED-5510-4EBD-AACE-5D3CBB7516DB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A8FD8CED-5510-4EBD-AACE-5D3CBB7516DB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A8FD8CED-5510-4EBD-AACE-5D3CBB7516DB}.Release|Any CPU.Build.0 = Release|Any CPU - {4D852DF8-9327-43D0-93AB-FA68D4F3414B}.Debug|Any CPU.ActiveCfg = Debug - {4D852DF8-9327-43D0-93AB-FA68D4F3414B}.Release|Any CPU.ActiveCfg = Release - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {AB7EF6F7-C38B-4E66-BBF9-1F6915896CB0} - EndGlobalSection -EndGlobal diff --git a/jslib b/jslib new file mode 160000 index 00000000..5d3b99ce --- /dev/null +++ b/jslib @@ -0,0 +1 @@ +Subproject commit 5d3b99ce6f93c3c43adc9e3eb784bc00b728a7f2 diff --git a/package-lock.json b/package-lock.json index b7c77c70..f296cae6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -955,6 +955,12 @@ "isarray": "1.0.0" } }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true + }, "buffer-equal-constant-time": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", @@ -2723,6 +2729,15 @@ "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", "dev": true }, + "encoding": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", + "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", + "dev": true, + "requires": { + "iconv-lite": "0.4.21" + } + }, "end-of-stream": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", @@ -3718,7 +3733,8 @@ "jsbn": { "version": "0.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "json-schema": { "version": "0.2.3", @@ -4393,6 +4409,52 @@ "retry-axios": "0.3.2" } }, + "google-fonts-webpack-plugin": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/google-fonts-webpack-plugin/-/google-fonts-webpack-plugin-0.4.4.tgz", + "integrity": "sha512-+e2D9/DVBG9EDydRovzoqMZ658SsTBGbC0c65GyZqkwNvdj8vRSYQKXqbz7/yt7QaXsCPT1MpH45r3ivWOitcw==", + "dev": true, + "requires": { + "lodash": "4.17.5", + "node-fetch": "1.7.3", + "webpack-sources": "0.2.3", + "yauzl": "2.9.1" + }, + "dependencies": { + "source-list-map": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-1.1.2.tgz", + "integrity": "sha1-mIkBnRAkzOVc3AaUmDN+9hhqEaE=", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "webpack-sources": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-0.2.3.tgz", + "integrity": "sha1-F8Yr+vE8cH+dAsR54Nzd6DgGl/s=", + "dev": true, + "requires": { + "source-list-map": "1.1.2", + "source-map": "0.5.7" + } + }, + "yauzl": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.9.1.tgz", + "integrity": "sha1-qBmB6nCleUYTOIPwKcWCGok1mn8=", + "dev": true, + "requires": { + "buffer-crc32": "0.2.13", + "fd-slicer": "1.0.1" + } + } + } + }, "google-p12-pem": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-1.0.2.tgz", @@ -5980,6 +6042,16 @@ "semver": "5.5.0" } }, + "node-fetch": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", + "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", + "dev": true, + "requires": { + "encoding": "0.1.12", + "is-stream": "1.1.0" + } + }, "node-forge": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.1.tgz", diff --git a/package.json b/package.json index 69a6838c..a0d09ae5 100644 --- a/package.json +++ b/package.json @@ -61,6 +61,7 @@ "extract-text-webpack-plugin": "^3.0.1", "file-loader": "^1.1.5", "font-awesome": "4.7.0", + "google-fonts-webpack-plugin": "^0.4.4", "html-loader": "^0.5.1", "html-webpack-plugin": "^2.30.1", "node-loader": "^0.6.0", diff --git a/src/Console/Console.csproj b/src/Console/Console.csproj deleted file mode 100644 index 19c610bb..00000000 --- a/src/Console/Console.csproj +++ /dev/null @@ -1,13 +0,0 @@ - - - - Exe - net461 - Bit.Console - - - - - - - diff --git a/src/Console/Program.cs b/src/Console/Program.cs deleted file mode 100644 index 32e7e010..00000000 --- a/src/Console/Program.cs +++ /dev/null @@ -1,1156 +0,0 @@ -using Bit.Core.Enums; -using Bit.Core.Models; -using Bit.Core.Services; -using Bit.Core.Utilities; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Con = System.Console; - -namespace Bit.Console -{ - public class Program - { - private static bool _usingArgs = false; - private static bool _exit = false; - private static string[] _args = null; - - static void Main(string[] args) - { - MainAsync(args).Wait(); - } - - private static async Task MainAsync(string[] args) - { - _args = args; - _usingArgs = args.Length > 0; - string selection = null; - - Con.ForegroundColor = ConsoleColor.Cyan; - Con.WriteLine(@" _ _ _ _ -| |__ (_) |___ ____ _ _ __ __| | ___ _ __ -| '_ \| | __\ \ /\ / / _` | '__/ _` |/ _ \ '_ \ -| |_) | | |_ \ V V / (_| | | | (_| | __/ | | | -|_.__/|_|\__| \_/\_/ \__,_|_| \__,_|\___|_| |_|"); - Con.ResetColor(); - Con.WriteLine(); - Con.WriteLine(Constants.ProgramName); - Con.WriteLine("Copyright 2015-{0}, 8bit Solutions LLC", DateTime.Now.Year); - Con.WriteLine(); - Con.WriteLine("https://bitwarden.com"); - Con.WriteLine("https://github.com/bitwarden/directory-connector"); - Con.WriteLine(); - - while(true) - { - Con.ResetColor(); - - if(_usingArgs) - { - selection = args[0]; - } - else - { - Con.WriteLine("Main Menu"); - Con.WriteLine("================================="); - Con.WriteLine("1. Log in to Bitwarden"); - Con.WriteLine("2. Log out"); - Con.WriteLine("3. Configure directory connection"); - Con.WriteLine("4. Configure sync"); - Con.WriteLine("5. Simulate directory sync"); - Con.WriteLine("6. Sync directory"); - Con.WriteLine("7. Control background service"); - Con.WriteLine("8. Configure environment"); - Con.WriteLine("9. Clear sync cache"); - Con.WriteLine("10. Exit"); - Con.WriteLine(); - Con.Write("What would you like to do? "); - selection = Con.ReadLine(); - Con.WriteLine(); - } - - switch(selection) - { - case "1": - case "login": - case "signin": - await LogInAsync(); - break; - case "2": - case "logout": - case "signout": - await LogOutAsync(); - break; - case "3": - case "cdir": - case "configdirectory": - await ConfigDirectoryAsync(); - break; - case "4": - case "csync": - case "configsync": - await ConfigSyncAsync(); - break; - case "5": - case "print": - case "sim": - case "simulate": - await PrintAsync(); - break; - case "6": - case "sync": - await SyncAsync(); - break; - case "7": - case "svc": - case "service": - await ServiceAsync(); - break; - case "8": - case "environnment": - case "env": - await ConfigEnvironmentAsync(); - break; - case "9": - case "cache": - case "clearcache": - await ClearCacheAsync(); - break; - case "10": - case "exit": - case "quit": - case "q": - _exit = true; - break; - default: - Con.WriteLine("Unknown command."); - break; - } - - if(_exit || _usingArgs) - { - break; - } - else - { - Con.WriteLine(); - Con.WriteLine(); - } - } - - _args = null; - } - - private static async Task LogInAsync() - { - if(AuthService.Instance.Authenticated) - { - Con.WriteLine("You are already logged in as {0}.", TokenService.Instance.AccessTokenEmail); - return; - } - - string email = null; - string masterPassword = null; - string token = null; - string orgId = null; - var provider = TwoFactorProviderType.Authenticator; - - if(_usingArgs) - { - var parameters = ParseParameters(); - if(parameters.Count >= 2 && parameters.ContainsKey("e") && parameters.ContainsKey("p")) - { - email = parameters["e"]; - masterPassword = parameters["p"]; - } - if(parameters.Count >= 4 && parameters.ContainsKey("t") && parameters.ContainsKey("tp") && - Enum.TryParse(parameters["tp"], out provider)) - { - token = parameters["t"]; - } - if(parameters.Count >= 3 && parameters.ContainsKey("o")) - { - orgId = parameters["o"]; - } - } - else - { - Con.Write("Email: "); - email = Con.ReadLine().Trim(); - Con.Write("Master password: "); - masterPassword = ReadSecureLine(); - } - - if(string.IsNullOrWhiteSpace(email) || string.IsNullOrWhiteSpace(masterPassword)) - { - Con.WriteLine(); - Con.WriteLine(); - WriteErrorLine("Invalid input parameters."); - return; - } - - Con.WriteLine(); - Con.WriteLine("Logging in..."); - LoginResult result = null; - if(string.IsNullOrWhiteSpace(token)) - { - result = await AuthService.Instance.LogInAsync(email, masterPassword); - } - else - { - result = await AuthService.Instance.LogInTwoFactorAsync(provider, token, - email, masterPassword); - } - - if(string.IsNullOrWhiteSpace(token) && result.TwoFactorRequired) - { - Con.WriteLine(); - Con.WriteLine(); - Con.WriteLine("Two-step login is enabled on this account."); - if(result.TwoFactorProviders.Count > 1) - { - for(var i = 0; i < result.TwoFactorProviders.Count; i++) - { - Con.WriteLine("{0}. {1}{2}", i + 1, result.TwoFactorProviders.ElementAt(i).Key, - result.TwoFactorProviders.ElementAt(i).Key == TwoFactorProviderType.Duo || - result.TwoFactorProviders.ElementAt(i).Key == TwoFactorProviderType.OrganizationDuo || - result.TwoFactorProviders.ElementAt(i).Key == TwoFactorProviderType.U2f ? - " - not supported" : string.Empty); - } - Con.WriteLine(); - Con.Write("Which provider would you like to use?: "); - var providerIndexInput = Con.ReadLine().Trim(); - int providerIndex; - if(int.TryParse(providerIndexInput, out providerIndex) && result.TwoFactorProviders.Count >= providerIndex) - { - provider = result.TwoFactorProviders.ElementAt(providerIndex - 1).Key; - } - else - { - provider = result.TwoFactorProviders.First().Key; - } - } - else - { - provider = result.TwoFactorProviders.First().Key; - Con.WriteLine(); - } - - var readingTokenInput = true; - if(provider == TwoFactorProviderType.YubiKey) - { - Con.Write("Tap the button on your YubiKey: "); - } - else if(provider == TwoFactorProviderType.Email) - { - if(result.TwoFactorProviders.Count > 1) - { - await ApiService.Instance.PostTwoFactorSendEmailLoginAsync(new TwoFactorEmailRequest - { - Email = email, - MasterPasswordHash = result.MasterPasswordHash - }); - } - - Con.Write("Enter the verification code that was emailed to you: "); - } - else if(provider == TwoFactorProviderType.Authenticator) - { - Con.Write("Enter the verification code from your authenticator app: "); - } - else - { - Con.WriteLine("The selected two-step login method is not supported on this " + - "platform/application. Use a different two step-login method."); - readingTokenInput = false; - } - - if(readingTokenInput) - { - token = Con.ReadLine().Trim(); - result = await AuthService.Instance.LogInTwoFactorWithHashAsync(provider, token, email, - result.MasterPasswordHash); - } - } - - if(result.Success && result.Organizations != null && result.Organizations.Count > 1) - { - Organization org = null; - if(!string.IsNullOrWhiteSpace(orgId)) - { - org = result.Organizations.FirstOrDefault(o => o.Id == orgId); - } - else - { - Con.WriteLine(); - Con.WriteLine(); - for(int i = 0; i < result.Organizations.Count; i++) - { - Con.WriteLine("{0}. {1}", i + 1, result.Organizations[i].Name); - } - Con.WriteLine(); - Con.Write("Select your organization: "); - var orgIndexInput = Con.ReadLine().Trim(); - int orgIndex; - if(int.TryParse(orgIndexInput, out orgIndex) && result.Organizations.Count >= orgIndex) - { - org = result.Organizations[orgIndex - 1]; - } - } - - if(org == null) - { - result.Success = false; - result.ErrorMessage = "Organization not found."; - AuthService.Instance.LogOut(); - } - else - { - SettingsService.Instance.Organization = org; - } - } - - Con.WriteLine(); - Con.WriteLine(); - if(result.Success) - { - if(!result.TwoFactorRequired) - { - WriteSuccessLine(string.Format("You have successfully logged in as {0}!", - TokenService.Instance.AccessTokenEmail)); - } - else - { - WriteErrorLine("Unable to log in."); - } - } - else - { - WriteErrorLine(result.ErrorMessage); - } - - masterPassword = null; - } - - private static Task LogOutAsync() - { - if(AuthService.Instance.Authenticated) - { - AuthService.Instance.LogOut(); - WriteSuccessLine("You have successfully logged out!"); - } - else - { - WriteErrorLine("You are not logged in."); - } - - return Task.FromResult(0); - } - - private static Task ConfigDirectoryAsync() - { - var config = SettingsService.Instance.Server ?? new ServerConfiguration(); - - if(_usingArgs) - { - var parameters = ParseParameters(); - if(parameters.ContainsKey("t")) - { - DirectoryType dirType; - if(Enum.TryParse(parameters["t"], out dirType)) - { - config.Type = dirType; - } - else - { - WriteErrorLine("Unable to parse type parameter."); - return Task.FromResult(0); - } - } - - if(config.Type == DirectoryType.AzureActiveDirectory) - { - config.Azure = new AzureConfiguration(); - - if(parameters.ContainsKey("i")) - { - config.Azure.Id = parameters["i"]; - } - - if(parameters.ContainsKey("s")) - { - config.Azure.Secret = new EncryptedData(parameters["s"]); - } - - if(parameters.ContainsKey("te")) - { - config.Azure.Tenant = parameters["te"]; - } - } - else if(config.Type == DirectoryType.GSuite) - { - config.GSuite = new GSuiteConfiguration(); - - if(parameters.ContainsKey("f")) - { - config.GSuite.SecretFile = parameters["f"]; - } - - if(parameters.ContainsKey("u")) - { - config.GSuite.AdminUser = parameters["u"]; - } - - if(parameters.ContainsKey("d")) - { - config.GSuite.Domain = parameters["d"]; - config.GSuite.Customer = null; - } - else if(parameters.ContainsKey("c")) - { - config.GSuite.Customer = parameters["c"]; - config.GSuite.Domain = null; - } - } - else - { - config.Ldap = config.Ldap ?? new LdapConfiguration(); - if(parameters.ContainsKey("a")) - { - config.Ldap.Address = parameters["a"]; - } - - if(parameters.ContainsKey("port")) - { - config.Ldap.Port = parameters["port"]; - } - - if(parameters.ContainsKey("path")) - { - config.Ldap.Path = parameters["path"]; - } - - if(parameters.ContainsKey("cu")) - { - config.Ldap.Username = null; - config.Ldap.Password = null; - } - else - { - if(parameters.ContainsKey("u")) - { - config.Ldap.Username = parameters["u"]; - } - - if(parameters.ContainsKey("p")) - { - config.Ldap.Password = new EncryptedData(parameters["p"]); - } - } - } - } - else - { - string input; - - Con.WriteLine("1. Active Directory"); - Con.WriteLine("2. Azure Active Directory "); - Con.WriteLine("3. G Suite Directory"); - Con.WriteLine("4. Other LDAP Directory"); - - string currentType; - switch(config.Type) - { - case DirectoryType.ActiveDirectory: - currentType = "1"; - break; - case DirectoryType.AzureActiveDirectory: - currentType = "2"; - break; - case DirectoryType.GSuite: - currentType = "3"; - break; - default: - currentType = "4"; - break; - } - Con.WriteLine(); - Con.Write("Type [{0}]: ", currentType); - input = Con.ReadLine(); - if(!string.IsNullOrEmpty(input)) - { - switch(input) - { - case "1": - config.Type = DirectoryType.ActiveDirectory; - break; - case "2": - config.Type = DirectoryType.AzureActiveDirectory; - break; - case "3": - config.Type = DirectoryType.GSuite; - break; - default: - config.Type = DirectoryType.Other; - break; - } - } - - if(config.Type == DirectoryType.AzureActiveDirectory) - { - config.Azure = config.Azure ?? new AzureConfiguration(); - - Con.Write("Tenant [{0}]: ", config.Azure.Tenant); - input = Con.ReadLine(); - if(!string.IsNullOrEmpty(input)) - { - config.Azure.Tenant = input.Trim(); - } - Con.Write("Application Id [{0}]: ", config.Azure.Id); - input = Con.ReadLine(); - if(!string.IsNullOrEmpty(input)) - { - config.Azure.Id = input.Trim(); - } - Con.Write("Secret key: "); - input = Con.ReadLine(); - if(!string.IsNullOrEmpty(input)) - { - config.Azure.Secret = new EncryptedData(input.Trim()); - input = null; - } - } - else if(config.Type == DirectoryType.GSuite) - { - config.GSuite = config.GSuite ?? new GSuiteConfiguration(); - - Con.Write("Secret file [{0}]: ", config.GSuite.SecretFile); - input = Con.ReadLine(); - if(!string.IsNullOrEmpty(input)) - { - config.GSuite.SecretFile = input.Trim(); - } - Con.Write("Domain [{0}]: ", config.GSuite.Domain); - input = Con.ReadLine(); - if(!string.IsNullOrEmpty(input)) - { - config.GSuite.Domain = input.Trim(); - config.GSuite.Customer = null; - } - Con.Write("Admin user [{0}]: ", config.GSuite.AdminUser); - input = Con.ReadLine(); - if(!string.IsNullOrEmpty(input)) - { - config.GSuite.AdminUser = input.Trim(); - } - } - else - { - config.Ldap = config.Ldap ?? new LdapConfiguration(); - - Con.Write("Address [{0}]: ", config.Ldap.Address); - input = Con.ReadLine(); - if(!string.IsNullOrEmpty(input)) - { - config.Ldap.Address = input.Trim(); - } - Con.Write("Port [{0}]: ", config.Ldap.Port); - input = Con.ReadLine(); - if(!string.IsNullOrEmpty(input)) - { - config.Ldap.Port = input.Trim(); - } - Con.Write("Path [{0}]: ", config.Ldap.Path); - input = Con.ReadLine(); - if(!string.IsNullOrEmpty(input)) - { - config.Ldap.Path = input.Trim(); - } - - var currentUser = string.IsNullOrWhiteSpace(config.Ldap.Username) && - config.Ldap.Password == null; - Con.Write("Authenticate as current user? [{0}]: ", currentUser ? "y" : "n"); - input = Con.ReadLine().ToLower(); - if(!string.IsNullOrEmpty(input)) - { - currentUser = input == "y" || input == "yes"; - } - - if(currentUser) - { - config.Ldap.Username = null; - config.Ldap.Password = null; - } - else - { - Con.Write("Username [{0}]: ", config.Ldap.Username); - input = Con.ReadLine(); - if(!string.IsNullOrEmpty(input)) - { - config.Ldap.Username = input.Trim(); - } - Con.Write("Password: "); - input = ReadSecureLine(); - if(!string.IsNullOrEmpty(input)) - { - config.Ldap.Password = new EncryptedData(input); - input = null; - } - } - } - - input = null; - } - - Con.WriteLine(); - Con.WriteLine(); - if(config.Ldap != null && string.IsNullOrWhiteSpace(config.Ldap.Address)) - { - WriteErrorLine("Invalid input parameters."); - } - else if(config.Azure != null && (string.IsNullOrWhiteSpace(config.Azure.Id) || - config.Azure.Secret == null || string.IsNullOrWhiteSpace(config.Azure.Tenant))) - { - WriteErrorLine("Invalid input parameters."); - } - else - { - SettingsService.Instance.Server = config; - WriteSuccessLine("Saved directory server configuration."); - } - - return Task.FromResult(0); - } - - private static Task ConfigSyncAsync() - { - var config = SettingsService.Instance.Sync ?? - new SyncConfiguration(SettingsService.Instance.Server.Type); - - if(_usingArgs) - { - var parameters = ParseParameters(); - - config.SyncGroups = parameters.ContainsKey("g"); - config.SyncUsers = parameters.ContainsKey("u"); - - int intervalMinutes; - if(parameters.ContainsKey("i") && int.TryParse(parameters["i"], out intervalMinutes)) - { - config.IntervalMinutes = intervalMinutes; - } - - if(parameters.ContainsKey("uf")) - { - config.UserFilter = parameters["uf"]; - } - if(parameters.ContainsKey("gf")) - { - config.GroupFilter = parameters["gf"]; - } - - config.RemoveDisabledUsers = parameters.ContainsKey("rd"); - - if(SettingsService.Instance.Server.Type == DirectoryType.ActiveDirectory || - SettingsService.Instance.Server.Type == DirectoryType.Other) - { - if(parameters.ContainsKey("go")) - { - config.Ldap.GroupObjectClass = parameters["go"]; - } - if(parameters.ContainsKey("gp")) - { - config.Ldap.GroupPath = parameters["gp"]; - } - if(parameters.ContainsKey("gn")) - { - config.Ldap.GroupNameAttribute = parameters["gn"]; - } - - if(parameters.ContainsKey("uo")) - { - config.Ldap.UserObjectClass = parameters["uo"]; - } - if(parameters.ContainsKey("up")) - { - config.Ldap.UserPath = parameters["up"]; - } - if(parameters.ContainsKey("ue")) - { - config.Ldap.UserEmailAttribute = parameters["ue"]; - } - - if(parameters.ContainsKey("m")) - { - config.Ldap.MemberAttribute = parameters["m"]; - } - - config.Ldap.EmailPrefixSuffix = parameters.ContainsKey("ps"); - - if(parameters.ContainsKey("ep")) - { - config.Ldap.UserEmailPrefixAttribute = parameters["ep"]; - } - - if(parameters.ContainsKey("es")) - { - config.Ldap.UserEmailSuffix = parameters["es"]; - } - - if(parameters.ContainsKey("c")) - { - config.Ldap.CreationDateAttribute = parameters["c"]; - } - - if(parameters.ContainsKey("r")) - { - config.Ldap.RevisionDateAttribute = parameters["r"]; - } - } - } - else - { - string input; - - Con.Write("Sync groups? [{0}]: ", config.SyncGroups ? "y" : "n"); - input = Con.ReadLine().ToLower(); - if(!string.IsNullOrEmpty(input)) - { - config.SyncGroups = input == "y" || input == "yes"; - } - if(config.SyncGroups && (SettingsService.Instance.Server.Type == DirectoryType.ActiveDirectory || - SettingsService.Instance.Server.Type == DirectoryType.Other)) - { - Con.Write("Group path [{0}]: ", config.Ldap.GroupPath); - input = Con.ReadLine(); - if(!string.IsNullOrEmpty(input)) - { - config.Ldap.GroupPath = input; - } - Con.Write("Group object class [{0}]: ", config.Ldap.GroupObjectClass); - input = Con.ReadLine(); - if(!string.IsNullOrEmpty(input)) - { - config.Ldap.GroupObjectClass = input; - } - Con.Write("Group name attribute [{0}]: ", config.Ldap.GroupNameAttribute); - input = Con.ReadLine(); - if(!string.IsNullOrEmpty(input)) - { - config.Ldap.GroupNameAttribute = input; - } - Con.Write("Member Attribute [{0}]: ", config.Ldap.MemberAttribute); - input = Con.ReadLine(); - if(!string.IsNullOrEmpty(input)) - { - config.Ldap.MemberAttribute = input; - } - } - if(config.SyncGroups) - { - Con.Write("Group filter [{0}]: ", config.GroupFilter); - input = Con.ReadLine(); - if(!string.IsNullOrEmpty(input)) - { - config.GroupFilter = input; - } - } - - Con.Write("Sync users? [{0}]: ", config.SyncUsers ? "y" : "n"); - input = Con.ReadLine().ToLower(); - if(!string.IsNullOrEmpty(input)) - { - config.SyncUsers = input == "y" || input == "yes"; - } - if(config.SyncUsers && (SettingsService.Instance.Server.Type == DirectoryType.ActiveDirectory || - SettingsService.Instance.Server.Type == DirectoryType.Other)) - { - Con.Write("User path [{0}]: ", config.Ldap.UserPath); - input = Con.ReadLine(); - if(!string.IsNullOrEmpty(input)) - { - config.Ldap.UserPath = input; - } - Con.Write("User object class [{0}]: ", config.Ldap.UserObjectClass); - input = Con.ReadLine(); - if(!string.IsNullOrEmpty(input)) - { - config.Ldap.UserObjectClass = input; - } - Con.Write("User email attribute [{0}]: ", config.Ldap.UserEmailAttribute); - input = Con.ReadLine(); - if(!string.IsNullOrEmpty(input)) - { - config.Ldap.GroupNameAttribute = input; - } - - Con.Write("Use email prefix/suffix fallback? [{0}]: ", config.Ldap.EmailPrefixSuffix ? "y" : "n"); - input = Con.ReadLine().ToLower(); - if(!string.IsNullOrEmpty(input)) - { - config.Ldap.EmailPrefixSuffix = input == "y" || input == "yes"; - } - - if(config.Ldap.EmailPrefixSuffix) - { - Con.Write("Email prefix attribute [{0}]: ", config.Ldap.UserEmailPrefixAttribute); - input = Con.ReadLine(); - if(!string.IsNullOrEmpty(input)) - { - config.Ldap.UserEmailPrefixAttribute = input; - } - Con.Write("Email suffix [{0}]: ", config.Ldap.UserEmailSuffix); - input = Con.ReadLine(); - if(!string.IsNullOrEmpty(input)) - { - config.Ldap.UserEmailSuffix = input; - } - } - } - if(config.SyncUsers) - { - Con.Write("User filter [{0}]: ", config.UserFilter); - input = Con.ReadLine(); - if(!string.IsNullOrEmpty(input)) - { - config.UserFilter = input; - } - Con.Write("Remove disabled users? [{0}]: ", config.RemoveDisabledUsers ? "y" : "n"); - input = Con.ReadLine().ToLower(); - if(!string.IsNullOrEmpty(input)) - { - config.RemoveDisabledUsers = input == "y" || input == "yes"; - } - } - - if(SettingsService.Instance.Server.Type == DirectoryType.ActiveDirectory || - SettingsService.Instance.Server.Type == DirectoryType.Other) - { - Con.Write("Creation Attribute [{0}]: ", config.Ldap.CreationDateAttribute); - input = Con.ReadLine(); - if(!string.IsNullOrEmpty(input)) - { - config.Ldap.CreationDateAttribute = input; - } - Con.Write("Changed Attribute [{0}]: ", config.Ldap.RevisionDateAttribute); - input = Con.ReadLine(); - if(!string.IsNullOrEmpty(input)) - { - config.Ldap.RevisionDateAttribute = input; - } - } - - Con.Write("Sync interval (minutes, minimum {1}) [{0}]: ", config.IntervalMinutes, "5"); - input = Con.ReadLine(); - int intervalMinutes; - if(!string.IsNullOrEmpty(input) && int.TryParse(input, out intervalMinutes)) - { - config.IntervalMinutes = intervalMinutes; - } - - input = null; - } - - Con.WriteLine(); - Con.WriteLine(); - SettingsService.Instance.Sync = config; - WriteSuccessLine("Saved sync configuration."); - - return Task.FromResult(0); - } - - private static async Task SyncAsync() - { - if(!AuthService.Instance.Authenticated) - { - Con.WriteLine("You are not logged in."); - } - else if(SettingsService.Instance.Server == null) - { - Con.WriteLine("Server is not configured."); - } - else - { - var force = false; - if(_usingArgs) - { - var parameters = ParseParameters(); - force = parameters.ContainsKey("f"); - } - - Con.WriteLine("Syncing..."); - var result = await Sync.SyncAllAsync(force, true); - - if(result.Success) - { - WriteSuccessLine(string.Format("Syncing complete ({0} users, {1} groups).", - result.Users?.Count ?? 0, result.Groups?.Count ?? 0)); - } - else - { - WriteErrorLine("Syncing failed.\n" + result.ErrorMessage); - } - } - } - - private static async Task PrintAsync() - { - if(!AuthService.Instance.Authenticated) - { - Con.WriteLine("You are not logged in."); - } - else if(SettingsService.Instance.Server == null) - { - Con.WriteLine("Server is not configured."); - } - else - { - var force = false; - if(_usingArgs) - { - var parameters = ParseParameters(); - force = parameters.ContainsKey("f"); - } - - Con.WriteLine("Querying..."); - Con.WriteLine(); - - var result = await Sync.SyncAllAsync(force, false); - if(result.Success) - { - if(result.Groups != null) - { - Con.WriteLine("Groups:"); - - foreach(var group in result.Groups) - { - Con.WriteLine(" {0} - {1}", group.Name, group.ExternalId); - foreach(var user in group.UserMemberExternalIds) - { - Con.WriteLine(" {0}", user); - } - } - } - - if(result.Users != null) - { - Con.WriteLine(); - Con.WriteLine("Users:"); - - foreach(var user in result.Users) - { - Con.WriteLine(" {0}{1}{2}", user.Email ?? user.ExternalId, - user.Disabled ? " (-)" : null, user.Deleted ? " (X)" : null); - } - } - } - else - { - WriteErrorLine("Querying failed.\n" + result.ErrorMessage); - } - } - } - - private static Task ServiceAsync() - { - try - { - Con.WriteLine("Service current status: {0}", ControllerService.Instance.StatusString); - Con.WriteLine(); - } - catch - { - Con.WriteLine("Service unavailable."); - return Task.FromResult(0); - } - - var start = false; - var stop = false; - var status = false; - if(_usingArgs) - { - var parameters = ParseParameters(); - if(parameters.ContainsKey("start")) - { - start = true; - } - else if(parameters.ContainsKey("stop")) - { - stop = true; - } - } - else - { - Con.WriteLine("1. Start service"); - Con.WriteLine("2. Stop service"); - Con.WriteLine("3. Check service status"); - Con.WriteLine("4. Nothing, go back"); - Con.WriteLine(); - Con.Write("Option: "); - var selection = Con.ReadLine(); - - switch(selection) - { - case "1": - case "start": - start = true; - break; - case "2": - case "stop": - stop = true; - break; - case "3": - case "status": - status = true; - break; - default: - break; - } - } - - Con.WriteLine(); - - if((start || stop) && !Helpers.IsAdministrator()) - { - WriteErrorLine("You must be an administrator to control the service."); - return Task.FromResult(0); - } - - if(start) - { - Con.WriteLine("Starting service..."); - ControllerService.Instance.Start(); - } - else if(stop) - { - Con.WriteLine("Stopping service..."); - ControllerService.Instance.Stop(); - } - else if(status) - { - Con.WriteLine("Status: {0}", ControllerService.Instance.StatusString); - } - - return Task.FromResult(0); - } - - private static Task ConfigEnvironmentAsync() - { - if(_usingArgs) - { - var parameters = ParseParameters(); - if(parameters.ContainsKey("debug")) - { - SettingsService.Instance.ApiBaseUrl = "http://localhost:4000"; - SettingsService.Instance.IdentityBaseUrl = "http://localhost:33656"; - } - else - { - if(parameters.ContainsKey("api")) - { - SettingsService.Instance.ApiBaseUrl = parameters["api"]; - } - if(parameters.ContainsKey("id")) - { - SettingsService.Instance.IdentityBaseUrl = parameters["id"]; - } - } - } - else - { - var input = string.Empty; - - Con.Write("API [{0}]: ", SettingsService.Instance.ApiBaseUrl); - input = Con.ReadLine(); - if(input == "debug") - { - SettingsService.Instance.ApiBaseUrl = "http://localhost:4000"; - } - else if(!string.IsNullOrEmpty(input)) - { - SettingsService.Instance.ApiBaseUrl = input; - } - Con.Write("Identity [{0}]: ", SettingsService.Instance.IdentityBaseUrl); - input = Con.ReadLine(); - if(input == "debug") - { - SettingsService.Instance.IdentityBaseUrl = "http://localhost:33656"; - } - else if(!string.IsNullOrEmpty(input)) - { - SettingsService.Instance.IdentityBaseUrl = input; - } - } - - return Task.FromResult(0); - } - - private static Task ClearCacheAsync() - { - SettingsService.Instance.GroupDeltaToken = null; - SettingsService.Instance.LastGroupSyncDate = null; - SettingsService.Instance.UserDeltaToken = null; - SettingsService.Instance.LastUserSyncDate = null; - SettingsService.Instance.LastSyncHash = null; - return Task.FromResult(0); - } - - private static string ReadSecureLine() - { - var input = string.Empty; - while(true) - { - var i = Con.ReadKey(true); - if(i.Key == ConsoleKey.Enter) - { - break; - } - else if(i.Key == ConsoleKey.Backspace) - { - if(input.Length > 0) - { - input = input.Remove(input.Length - 1); - Con.Write("\b \b"); - } - } - else - { - input = string.Concat(input, i.KeyChar); - Con.Write("*"); - } - } - return input; - } - - private static IDictionary ParseParameters() - { - var dict = new Dictionary(); - for(int i = 1; i < _args.Length; i = i + 2) - { - if(!_args[i].StartsWith("-")) - { - continue; - } - - dict.Add(_args[i].Substring(1), _args[i + 1]); - } - - return dict; - } - - private static void WriteErrorLine(string message) - { - Con.ForegroundColor = ConsoleColor.Red; - Con.WriteLine(message); - Con.ResetColor(); - } - - private static void WriteSuccessLine(string message) - { - Con.ForegroundColor = ConsoleColor.Green; - Con.WriteLine(message); - Con.ResetColor(); - } - } -} diff --git a/src/Core/Core.csproj b/src/Core/Core.csproj deleted file mode 100644 index a4845874..00000000 --- a/src/Core/Core.csproj +++ /dev/null @@ -1,25 +0,0 @@ - - - - net461 - Bit.Core - Core - - - - - - - - - - - - - - - - - - - diff --git a/src/Core/Enums/DirectoryType.cs b/src/Core/Enums/DirectoryType.cs deleted file mode 100644 index 74974c19..00000000 --- a/src/Core/Enums/DirectoryType.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Bit.Core.Enums -{ - public enum DirectoryType : byte - { - ActiveDirectory = 0, - AzureActiveDirectory = 1, - Other = 2, - GSuite = 3 - } -} diff --git a/src/Core/Enums/OrganizationUserStatusType.cs b/src/Core/Enums/OrganizationUserStatusType.cs deleted file mode 100644 index c370a013..00000000 --- a/src/Core/Enums/OrganizationUserStatusType.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Bit.Core.Enums -{ - public enum OrganizationUserStatusType : byte - { - Invited = 0, - Accepted = 1, - Confirmed = 2 - } -} diff --git a/src/Core/Enums/OrganizationUserType.cs b/src/Core/Enums/OrganizationUserType.cs deleted file mode 100644 index 73ddfd7d..00000000 --- a/src/Core/Enums/OrganizationUserType.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Bit.Core.Enums -{ - public enum OrganizationUserType : byte - { - Owner = 0, - Admin = 1, - User = 2 - } -} diff --git a/src/Core/Enums/TwoFactorProviderType.cs b/src/Core/Enums/TwoFactorProviderType.cs deleted file mode 100644 index 1a1b7ffc..00000000 --- a/src/Core/Enums/TwoFactorProviderType.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Bit.Core.Enums -{ - public enum TwoFactorProviderType : byte - { - Authenticator = 0, - Email = 1, - Duo = 2, - YubiKey = 3, - U2f = 4, - Remember = 5, - OrganizationDuo = 6 - } -} diff --git a/src/Core/Enums/UserAccountControl.cs b/src/Core/Enums/UserAccountControl.cs deleted file mode 100644 index 2cf9d36f..00000000 --- a/src/Core/Enums/UserAccountControl.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Bit.Core.Enums -{ - [Flags] - public enum UserAccountControl : int - { - AccountDisabled = 0x00000002, - LockOut = 0x00000010, - } -} diff --git a/src/Core/Models/ApiError.cs b/src/Core/Models/ApiError.cs deleted file mode 100644 index 29f08855..00000000 --- a/src/Core/Models/ApiError.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Bit.Core.Models -{ - public class ApiError - { - public string Message { get; set; } - } -} diff --git a/src/Core/Models/ApiResult.cs b/src/Core/Models/ApiResult.cs deleted file mode 100644 index 723f54b2..00000000 --- a/src/Core/Models/ApiResult.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System.Collections.Generic; -using System.Net; - -namespace Bit.Core.Models -{ - public class ApiResult - { - private List m_errors = new List(); - - public bool Succeeded { get; private set; } - public T Result { get; set; } - public IEnumerable Errors => m_errors; - public HttpStatusCode StatusCode { get; private set; } - - public static ApiResult Success(T result, HttpStatusCode statusCode) - { - return new ApiResult - { - Succeeded = true, - Result = result, - StatusCode = statusCode - }; - } - - public static ApiResult Failed(HttpStatusCode statusCode, params ApiError[] errors) - { - var result = new ApiResult - { - Succeeded = false, - StatusCode = statusCode - }; - - if(errors != null) - { - result.m_errors.AddRange(errors); - } - - return result; - } - } - - public class ApiResult - { - private List m_errors = new List(); - - public bool Succeeded { get; private set; } - public IEnumerable Errors => m_errors; - public HttpStatusCode StatusCode { get; private set; } - - public static ApiResult Success(HttpStatusCode statusCode) - { - return new ApiResult - { - Succeeded = true, - StatusCode = statusCode - }; - } - - public static ApiResult Failed(HttpStatusCode statusCode, params ApiError[] errors) - { - var result = new ApiResult - { - Succeeded = false, - StatusCode = statusCode - }; - - if(errors != null) - { - result.m_errors.AddRange(errors); - } - - return result; - } - } -} diff --git a/src/Core/Models/AzureConfiguration.cs b/src/Core/Models/AzureConfiguration.cs deleted file mode 100644 index de9964f4..00000000 --- a/src/Core/Models/AzureConfiguration.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Bit.Core.Models -{ - public class AzureConfiguration - { - public string Tenant { get; set; } = "yourcompany.onmicrosoft.com"; - public string Id { get; set; } - public EncryptedData Secret { get; set; } - } -} diff --git a/src/Core/Models/EncryptedData.cs b/src/Core/Models/EncryptedData.cs deleted file mode 100644 index 8d75a214..00000000 --- a/src/Core/Models/EncryptedData.cs +++ /dev/null @@ -1,60 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Security.Cryptography; -using System.Text; -using System.Threading.Tasks; - -namespace Bit.Core.Models -{ - public class EncryptedData - { - public EncryptedData() { } - - public EncryptedData(byte[] plainValue) - { - IV = RandomBytes(); -#if NET461 - Value = ProtectedData.Protect(plainValue, IV, DataProtectionScope.LocalMachine); -#endif - } - - public EncryptedData(string plainValue) - { - var bytes = Encoding.UTF8.GetBytes(plainValue); - IV = RandomBytes(); -#if NET461 - Value = ProtectedData.Protect(bytes, IV, DataProtectionScope.LocalMachine); -#endif - } - - public byte[] Value { get; set; } - public byte[] IV { get; set; } - - public byte[] Decrypt() - { -#if NET461 - return ProtectedData.Unprotect(Value, IV, DataProtectionScope.LocalMachine); -#else - return new byte[0]; -#endif - } - - public string DecryptToString() - { -#if NET461 - var bytes = ProtectedData.Unprotect(Value, IV, DataProtectionScope.LocalMachine); -#else - var bytes = new byte[0]; -#endif - return Encoding.UTF8.GetString(bytes); - } - - private byte[] RandomBytes() - { - var entropy = new byte[16]; - new RNGCryptoServiceProvider().GetBytes(entropy); - return entropy; - } - } -} diff --git a/src/Core/Models/Entry.cs b/src/Core/Models/Entry.cs deleted file mode 100644 index b62d0663..00000000 --- a/src/Core/Models/Entry.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Bit.Core.Models -{ - public abstract class Entry - { - public string ReferenceId { get; set; } - public string ExternalId { get; set; } - public DateTime? CreationDate { get; set; } - public DateTime? RevisionDate { get; set; } - } - - public class GroupEntry : Entry - { - public string Name { get; set; } - public HashSet UserMemberExternalIds { get; set; } = new HashSet(); - public HashSet GroupMemberReferenceIds { get; set; } = new HashSet(); - } - - public class UserEntry : Entry - { - public string Email { get; set; } - public bool Disabled { get; set; } - public bool Deleted { get; set; } - } -} diff --git a/src/Core/Models/ErrorResponse.cs b/src/Core/Models/ErrorResponse.cs deleted file mode 100644 index 45c59070..00000000 --- a/src/Core/Models/ErrorResponse.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Bit.Core.Models -{ - public class ErrorResponse - { - public string Message { get; set; } - public Dictionary> ValidationErrors { get; set; } - // For use in development environments. - public string ExceptionMessage { get; set; } - public string ExceptionStackTrace { get; set; } - public string InnerExceptionMessage { get; set; } - } -} diff --git a/src/Core/Models/GSuiteConfiguration.cs b/src/Core/Models/GSuiteConfiguration.cs deleted file mode 100644 index b597ea11..00000000 --- a/src/Core/Models/GSuiteConfiguration.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Bit.Core.Models -{ - public class GSuiteConfiguration - { - public string SecretFile { get; set; } = "client_secret.json"; - public string Customer { get; set; } - public string Domain { get; set; } = "yourcompany.com"; - public string AdminUser { get; set; } = "adminuser@yourcompany.com"; - } -} \ No newline at end of file diff --git a/src/Core/Models/ImportRequest.cs b/src/Core/Models/ImportRequest.cs deleted file mode 100644 index 8f00e248..00000000 --- a/src/Core/Models/ImportRequest.cs +++ /dev/null @@ -1,47 +0,0 @@ -using Bit.Core.Services; -using System.Collections.Generic; -using System.Linq; - -namespace Bit.Core.Models -{ - public class ImportRequest - { - public ImportRequest(List groups, List users) - { - Groups = groups?.Select(g => new Group(g)).ToArray() ?? new Group[] { }; - Users = users?.Select(u => new User(u)).ToArray() ?? new User[] { }; - } - - public Group[] Groups { get; set; } - public User[] Users { get; set; } - - public class Group - { - public Group(GroupEntry entry) - { - Name = entry.Name; - ExternalId = entry.ExternalId; - Users = entry.UserMemberExternalIds; - } - - public string Name { get; set; } - public string ExternalId { get; set; } - public IEnumerable Users { get; set; } - } - - public class User - { - public User(UserEntry entry) - { - Email = entry.Email; - Deleted = (SettingsService.Instance.Sync.RemoveDisabledUsers && entry.Disabled) || entry.Deleted; - ExternalId = entry.ExternalId; - } - - public string ExternalId { get; set; } - public string Email { get; set; } - public bool Deleted { get; set; } - } - } - -} diff --git a/src/Core/Models/LdapConfiguration.cs b/src/Core/Models/LdapConfiguration.cs deleted file mode 100644 index 1cd4e343..00000000 --- a/src/Core/Models/LdapConfiguration.cs +++ /dev/null @@ -1,64 +0,0 @@ -using Bit.Core.Services; -using System; -#if NET461 -using System.DirectoryServices; -#endif - -namespace Bit.Core.Models -{ - public class LdapConfiguration - { - public string Address { get; set; } - public string Port { get; set; } = "389"; - public string Path { get; set; } - public string Username { get; set; } - public EncryptedData Password { get; set; } - public Enums.DirectoryType Type { get; set; } = Enums.DirectoryType.ActiveDirectory; - -#if NET461 - public DirectoryEntry GetUserDirectoryEntry() - { - return GetPathedDirectoryEntry(SettingsService.Instance.Sync.Ldap.UserPath); - } - - public DirectoryEntry GetGroupDirectoryEntry() - { - return GetPathedDirectoryEntry(SettingsService.Instance.Sync.Ldap.GroupPath); - } - - public DirectoryEntry GetPathedDirectoryEntry(string pathPrefix = null) - { - var path = Path; - if(!string.IsNullOrWhiteSpace(pathPrefix)) - { - path = string.Concat(pathPrefix, ",", path); - } - - return GetDirectoryEntry(path); - } - - public DirectoryEntry GetBasePathDirectoryEntry() - { - var path = Path.Substring(Path.IndexOf("dc=", StringComparison.InvariantCultureIgnoreCase)); - return GetDirectoryEntry(path); - } - - public DirectoryEntry GetDirectoryEntry(string path = null) - { - if(Password == null && string.IsNullOrWhiteSpace(Username)) - { - return new DirectoryEntry(ServerPath(path)); - } - else - { - return new DirectoryEntry(ServerPath(path), Username, Password.DecryptToString(), AuthenticationTypes.None); - } - } -#endif - - private string ServerPath(string path) - { - return $"LDAP://{Address}:{Port}/{path}"; - } - } -} diff --git a/src/Core/Models/LoginResult.cs b/src/Core/Models/LoginResult.cs deleted file mode 100644 index 84bf6a99..00000000 --- a/src/Core/Models/LoginResult.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Bit.Core.Enums; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Bit.Core.Models -{ - public class LoginResult - { - public bool Success { get; set; } - public string ErrorMessage { get; set; } - public bool TwoFactorRequired => TwoFactorProviders != null && TwoFactorProviders.Count > 0; - public Dictionary> TwoFactorProviders { get; set; } - public string MasterPasswordHash { get; set; } - public List Organizations { get; set; } - } -} diff --git a/src/Core/Models/Organization.cs b/src/Core/Models/Organization.cs deleted file mode 100644 index 58fd85c3..00000000 --- a/src/Core/Models/Organization.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Bit.Core.Models -{ - public class Organization - { - public Organization() { } - - public Organization(ProfileOrganizationResponseModel org) - { - Name = org.Name; - Id = org.Id; - } - - public string Name { get; set; } - public string Id { get; set; } - } -} diff --git a/src/Core/Models/ProfileOrganizationResponse.cs b/src/Core/Models/ProfileOrganizationResponse.cs deleted file mode 100644 index ac823ead..00000000 --- a/src/Core/Models/ProfileOrganizationResponse.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Bit.Core.Enums; -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Bit.Core.Models -{ - public class ProfileOrganizationResponseModel - { - public string Id { get; set; } - public string Name { get; set; } - public string Key { get; set; } - public OrganizationUserStatusType Status { get; set; } - public OrganizationUserType Type { get; set; } - public bool Enabled { get; set; } - } -} diff --git a/src/Core/Models/ProfileResponse.cs b/src/Core/Models/ProfileResponse.cs deleted file mode 100644 index b7afc2ff..00000000 --- a/src/Core/Models/ProfileResponse.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Bit.Core.Models -{ - public class ProfileResponse - { - public string Id { get; set; } - public string Name { get; set; } - public string Email { get; set; } - public string MasterPasswordHint { get; set; } - public string Culture { get; set; } - public bool TwoFactorEnabled { get; set; } - public IEnumerable Organizations { get; set; } - } -} diff --git a/src/Core/Models/ServerConfiguration.cs b/src/Core/Models/ServerConfiguration.cs deleted file mode 100644 index 6e33f2a4..00000000 --- a/src/Core/Models/ServerConfiguration.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -namespace Bit.Core.Models -{ - public class ServerConfiguration - { - public Enums.DirectoryType Type { get; set; } = Enums.DirectoryType.ActiveDirectory; - public LdapConfiguration Ldap { get; set; } - public AzureConfiguration Azure { get; set; } - public GSuiteConfiguration GSuite { get; set; } - } -} diff --git a/src/Core/Models/SyncConfiguration.cs b/src/Core/Models/SyncConfiguration.cs deleted file mode 100644 index da86bbcb..00000000 --- a/src/Core/Models/SyncConfiguration.cs +++ /dev/null @@ -1,102 +0,0 @@ -using Bit.Core.Enums; - -namespace Bit.Core.Models -{ - public class SyncConfiguration - { - public SyncConfiguration() { } - - public SyncConfiguration(DirectoryType type) - { - Ldap = new LdapSyncConfiguration(type); - - switch(type) - { - case DirectoryType.ActiveDirectory: - break; - case DirectoryType.AzureActiveDirectory: - break; - case DirectoryType.Other: - break; - case DirectoryType.GSuite: - break; - default: - break; - } - } - - /* - * Depending on what server type you are using, filters are be one of the following: - * - * 1. ActiveDirectory or Other - * - LDAP query/filter syntax - * - Read more at: http://bit.ly/2qyLpzW - * - ex. "(&(givenName=John)(|(l=Dallas)(l=Austin)))" - * - * 2. AzureActiveDirectory - * - OData syntax for a Microsoft Graph query parameter '$filter' - * - Read more at http://bit.ly/2q3FOOD - * - ex. "startswith(displayName,'J')" - * - * 3. G Suite - * - Group Filter - * - Custom filtering syntax that allows you to exclude or include a comma separated list of group names. - * - ex. "include:Group A,Sales People,My Other Group" - * or "exclude:Group C,Developers,Some Other Group" - * - User Filter - * - Custom filtering syntax that allows you to exclude or include a comma separated list of group names. - * - Allows you to concatenate a G Suite Admin API user search query to the end of the filter after delimiting - * the include/exclude filter with a pipe (|). - * - Read more at http://bit.ly/2rlTskX - * - ex. - * or "include:joe@company.com,bill@company.com,tom@company.com" - * or "exclude:john@company.com,bill@company.com|orgName=Engineering orgTitle:Manager" - * or "|orgName=Engineering orgTitle:Manager" - */ - - public string GroupFilter { get; set; } - public string UserFilter { get; set; } - - public bool SyncGroups { get; set; } = true; - public bool SyncUsers { get; set; } = true; - public int IntervalMinutes { get; set; } = 5; - public bool RemoveDisabledUsers { get; set; } - public LdapSyncConfiguration Ldap { get; set; } = new LdapSyncConfiguration(); - - public class LdapSyncConfiguration - { - public LdapSyncConfiguration() { } - - public LdapSyncConfiguration(DirectoryType type) - { - switch(type) - { - case DirectoryType.ActiveDirectory: - CreationDateAttribute = "whenCreated"; - RevisionDateAttribute = "whenChanged"; - UserEmailPrefixAttribute = "sAMAccountName"; - UserPath = "CN=Users"; - GroupPath = "CN=Users"; - break; - case DirectoryType.Other: - break; - default: - break; - } - } - - public string UserPath { get; set; } - public string GroupPath { get; set; } - public string UserObjectClass { get; set; } = "person"; - public string GroupObjectClass { get; set; } = "group"; - public string MemberAttribute { get; set; } = "member"; - public string GroupNameAttribute { get; set; } = "name"; - public string UserEmailAttribute { get; set; } = "mail"; - public bool EmailPrefixSuffix { get; set; } = false; - public string UserEmailPrefixAttribute { get; set; } = "cn"; - public string UserEmailSuffix { get; set; } = "@companyname.com"; - public string CreationDateAttribute { get; set; } - public string RevisionDateAttribute { get; set; } - } - } -} diff --git a/src/Core/Models/SyncResult.cs b/src/Core/Models/SyncResult.cs deleted file mode 100644 index dced4d3b..00000000 --- a/src/Core/Models/SyncResult.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Bit.Core.Models -{ - public class SyncResult - { - public bool Success { get; set; } - public string ErrorMessage { get; set; } - public List Groups { get; set; } = new List(); - public List Users { get; set; } = new List(); - } -} diff --git a/src/Core/Models/TokenRequest.cs b/src/Core/Models/TokenRequest.cs deleted file mode 100644 index 8f7135e6..00000000 --- a/src/Core/Models/TokenRequest.cs +++ /dev/null @@ -1,36 +0,0 @@ -using Bit.Core.Enums; -using System; -using System.Collections.Generic; - -namespace Bit.Core.Models -{ - public class TokenRequest - { - public string Email { get; set; } - public string MasterPasswordHash { get; set; } - public string Token { get; set; } - public TwoFactorProviderType? Provider { get; set; } - public bool Remember { get; set; } - - public IDictionary ToIdentityTokenRequest() - { - var dict = new Dictionary - { - { "grant_type", "password" }, - { "username", Email }, - { "password", MasterPasswordHash }, - { "scope", "api offline_access" }, - { "client_id", "connector" } - }; - - if(Token != null && Provider.HasValue) - { - dict.Add("TwoFactorToken", Token); - dict.Add("TwoFactorProvider", ((byte)(Provider.Value)).ToString()); - dict.Add("TwoFactorRemember", Remember ? "1" : "0"); - } - - return dict; - } - } -} diff --git a/src/Core/Models/TokenResponse.cs b/src/Core/Models/TokenResponse.cs deleted file mode 100644 index 0fe96b54..00000000 --- a/src/Core/Models/TokenResponse.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Bit.Core.Enums; -using Newtonsoft.Json; -using System.Collections.Generic; - -namespace Bit.Core.Models -{ - public class TokenResponse - { - [JsonProperty("access_token")] - public string AccessToken { get; set; } - [JsonProperty("expires_in")] - public long ExpiresIn { get; set; } - [JsonProperty("refresh_token")] - public string RefreshToken { get; set; } - [JsonProperty("token_type")] - public string TokenType { get; set; } - public Dictionary> TwoFactorProviders2 { get; set; } - public string PrivateKey { get; set; } - public string TwoFactorToken { get; set; } - public string Key { get; set; } - } -} diff --git a/src/Core/Models/TwoFactorEmailRequest.cs b/src/Core/Models/TwoFactorEmailRequest.cs deleted file mode 100644 index d7a6a5ac..00000000 --- a/src/Core/Models/TwoFactorEmailRequest.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Bit.Core.Models -{ - public class TwoFactorEmailRequest - { - public string Email { get; set; } - public string MasterPasswordHash { get; set; } - } -} diff --git a/src/Core/Services/ApiService.cs b/src/Core/Services/ApiService.cs deleted file mode 100644 index acce8548..00000000 --- a/src/Core/Services/ApiService.cs +++ /dev/null @@ -1,322 +0,0 @@ -using Bit.Core.Enums; -using Bit.Core.Models; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.Net; -using System.Net.Http; -using System.Text; -using System.Threading.Tasks; - -namespace Bit.Core.Services -{ - public class ApiService - { - private static ApiService _instance; - - private ApiService() - { - Client = new HttpClient(); - } - - public static ApiService Instance - { - get - { - if(_instance == null) - { - _instance = new ApiService(); - } - - return _instance; - } - } - - protected HttpClient Client { get; private set; } - - public virtual async Task> PostTokenAsync(TokenRequest requestObj) - { - var requestMessage = new HttpRequestMessage - { - Method = HttpMethod.Post, - RequestUri = new Uri(string.Concat(SettingsService.Instance.IdentityBaseUrl, "/connect/token")), - Content = new FormUrlEncodedContent(requestObj.ToIdentityTokenRequest()) - }; - - try - { - var response = await Client.SendAsync(requestMessage).ConfigureAwait(false); - var responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - - if(!response.IsSuccessStatusCode) - { - var errorResponse = JObject.Parse(responseContent); - if(errorResponse["TwoFactorProviders2"] != null) - { - return ApiResult.Success(new TokenResponse - { - TwoFactorProviders2 = errorResponse["TwoFactorProviders2"] - .ToObject>>() - }, response.StatusCode); - } - - return await HandleErrorAsync(response).ConfigureAwait(false); - } - - var responseObj = JsonConvert.DeserializeObject(responseContent); - return ApiResult.Success(responseObj, response.StatusCode); - } - catch - { - return HandledWebException(); - } - } - - public virtual async Task PostImportAsync(ImportRequest requestObj) - { - var tokenStateResponse = await HandleTokenStateAsync(); - if(!tokenStateResponse.Succeeded) - { - return tokenStateResponse; - } - - var stringContent = JsonConvert.SerializeObject(requestObj); - var requestMessage = new HttpRequestMessage - { - Method = HttpMethod.Post, - RequestUri = new Uri(string.Concat(SettingsService.Instance.ApiBaseUrl, "/organizations/", - SettingsService.Instance.Organization.Id, "/import")), - Content = new StringContent(stringContent, Encoding.UTF8, "application/json"), - }; - - requestMessage.Headers.Add("Authorization", $"Bearer {TokenService.Instance.AccessToken}"); - - try - { - var response = await Client.SendAsync(requestMessage).ConfigureAwait(false); - if(!response.IsSuccessStatusCode) - { - return await HandleErrorAsync(response).ConfigureAwait(false); - } - - return ApiResult.Success(response.StatusCode); - } - catch - { - return HandledWebException(); - } - } - - public virtual async Task> GetProfileAsync() - { - var tokenStateResponse = await HandleTokenStateAsync(); - if(!tokenStateResponse.Succeeded) - { - return tokenStateResponse; - } - - var requestMessage = new HttpRequestMessage() - { - Method = HttpMethod.Get, - RequestUri = new Uri(string.Concat(SettingsService.Instance.ApiBaseUrl, "/accounts/profile")), - }; - - requestMessage.Headers.Add("Authorization", $"Bearer {TokenService.Instance.AccessToken}"); - - try - { - var response = await Client.SendAsync(requestMessage).ConfigureAwait(false); - if(!response.IsSuccessStatusCode) - { - return await HandleErrorAsync(response).ConfigureAwait(false); - } - - var responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var responseObj = JsonConvert.DeserializeObject(responseContent); - return ApiResult.Success(responseObj, response.StatusCode); - } - catch - { - return HandledWebException(); - } - } - - public virtual async Task PostTwoFactorSendEmailLoginAsync(TwoFactorEmailRequest requestObj) - { - var stringContent = JsonConvert.SerializeObject(requestObj); - - var requestMessage = new HttpRequestMessage() - { - Method = HttpMethod.Post, - RequestUri = new Uri(string.Concat(SettingsService.Instance.ApiBaseUrl, "/two-factor/send-email-login")), - Content = new StringContent(stringContent, Encoding.UTF8, "application/json") - }; - - try - { - var response = await Client.SendAsync(requestMessage).ConfigureAwait(false); - if(!response.IsSuccessStatusCode) - { - return await HandleErrorAsync(response).ConfigureAwait(false); - } - - return ApiResult.Success(response.StatusCode); - } - catch - { - return HandledWebException(); - } - } - - protected ApiResult HandledWebException() - { - return ApiResult.Failed(HttpStatusCode.BadGateway, - new ApiError { Message = "There is a problem connecting to the server." }); - } - - protected ApiResult HandledWebException() - { - return ApiResult.Failed(HttpStatusCode.BadGateway, - new ApiError { Message = "There is a problem connecting to the server." }); - } - - protected async Task HandleTokenStateAsync() - { - return await HandleTokenStateAsync( - () => ApiResult.Success(HttpStatusCode.OK), - () => HandledWebException(), - (r) => HandleErrorAsync(r)); - } - - protected async Task> HandleTokenStateAsync() - { - return await HandleTokenStateAsync( - () => ApiResult.Success(default(T), HttpStatusCode.OK), - () => HandledWebException(), - (r) => HandleErrorAsync(r)); - } - - private async Task HandleTokenStateAsync(Func success, Func webException, - Func> error) - { - if(TokenService.Instance.AccessTokenNeedsRefresh && !string.IsNullOrWhiteSpace(TokenService.Instance.RefreshToken)) - { - var requestMessage = new HttpRequestMessage - { - Method = HttpMethod.Post, - RequestUri = new Uri(string.Concat(SettingsService.Instance.IdentityBaseUrl, "/connect/token")), - Content = new FormUrlEncodedContent( - new Dictionary - { - { "grant_type", "refresh_token" }, - { "client_id", "connector" }, - { "refresh_token", TokenService.Instance.RefreshToken } - }) - }; - - try - { - var response = await Client.SendAsync(requestMessage).ConfigureAwait(false); - if(!response.IsSuccessStatusCode) - { - if(response.StatusCode == HttpStatusCode.BadRequest) - { - response.StatusCode = HttpStatusCode.Unauthorized; - } - - return await error.Invoke(response).ConfigureAwait(false); - } - - var responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - var tokenResponse = JsonConvert.DeserializeObject(responseContent); - TokenService.Instance.AccessToken = tokenResponse.AccessToken; - TokenService.Instance.RefreshToken = tokenResponse.RefreshToken; - } - catch - { - return webException.Invoke(); - } - } - - return success.Invoke(); - } - - protected async Task> HandleErrorAsync(HttpResponseMessage response) - { - try - { - var errors = await ParseErrorsAsync(response).ConfigureAwait(false); - return ApiResult.Failed(response.StatusCode, errors.ToArray()); - } - catch - { } - - return ApiResult.Failed(response.StatusCode, - new ApiError { Message = "An unknown error has occurred." }); - } - - protected async Task HandleErrorAsync(HttpResponseMessage response) - { - try - { - var errors = await ParseErrorsAsync(response).ConfigureAwait(false); - return ApiResult.Failed(response.StatusCode, errors.ToArray()); - } - catch - { } - - return ApiResult.Failed(response.StatusCode, - new ApiError { Message = "An unknown error has occurred." }); - } - - private async Task> ParseErrorsAsync(HttpResponseMessage response) - { - var errors = new List(); - var statusCode = (int)response.StatusCode; - if(statusCode >= 400 && statusCode <= 500) - { - ErrorResponse errorResponseModel = null; - - var responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false); - if(!string.IsNullOrWhiteSpace(responseContent)) - { - var errorResponse = JObject.Parse(responseContent); - if(errorResponse["ErrorModel"] != null && errorResponse["ErrorModel"]["Message"] != null) - { - errorResponseModel = errorResponse["ErrorModel"].ToObject(); - } - else if(errorResponse["Message"] != null) - { - errorResponseModel = errorResponse.ToObject(); - } - } - - if(errorResponseModel != null) - { - if((errorResponseModel.ValidationErrors?.Count ?? 0) > 0) - { - foreach(var valError in errorResponseModel.ValidationErrors) - { - foreach(var errorMessage in valError.Value) - { - errors.Add(new ApiError { Message = errorMessage }); - } - } - } - else - { - errors.Add(new ApiError { Message = errorResponseModel.Message }); - } - } - } - - if(errors.Count == 0) - { - errors.Add(new ApiError { Message = "An unknown error has occurred." }); - } - - return errors; - } - } -} diff --git a/src/Core/Services/AuthService.cs b/src/Core/Services/AuthService.cs deleted file mode 100644 index c1d67b1f..00000000 --- a/src/Core/Services/AuthService.cs +++ /dev/null @@ -1,155 +0,0 @@ -using Bit.Core.Enums; -using Bit.Core.Models; -using Bit.Core.Utilities; -using System.Linq; -using System.Threading.Tasks; - -namespace Bit.Core.Services -{ - public class AuthService - { - private static AuthService _instance; - - private AuthService() { } - - public static AuthService Instance - { - get - { - if(_instance == null) - { - _instance = new AuthService(); - } - - return _instance; - } - } - - public bool Authenticated => !string.IsNullOrWhiteSpace(TokenService.Instance.AccessToken); - public bool OrganizationSet => SettingsService.Instance.Organization != null; - - public void LogOut() - { - TokenService.Instance.AccessToken = null; - TokenService.Instance.RefreshToken = null; - } - - public async Task LogInAsync(string email, string masterPassword) - { - var normalizedEmail = email.Trim().ToLower(); - var key = Crypto.MakeKeyFromPassword(masterPassword, normalizedEmail); - - var request = new TokenRequest - { - Email = normalizedEmail, - MasterPasswordHash = Crypto.HashPasswordBase64(key, masterPassword) - }; - - var response = await ApiService.Instance.PostTokenAsync(request); - - masterPassword = null; - key = null; - - var result = new LoginResult(); - if(!response.Succeeded) - { - result.Success = false; - result.ErrorMessage = response.Errors.FirstOrDefault()?.Message; - return result; - } - - result.Success = true; - if(response.Result.TwoFactorProviders2 != null && response.Result.TwoFactorProviders2.Count > 0) - { - result.TwoFactorProviders = response.Result.TwoFactorProviders2; - result.MasterPasswordHash = request.MasterPasswordHash; - return result; - } - - return await ProcessLogInSuccessAsync(response.Result); - } - - public async Task LogInTwoFactorAsync(TwoFactorProviderType type, string token, string email, - string masterPassword) - { - var normalizedEmail = email.Trim().ToLower(); - var key = Crypto.MakeKeyFromPassword(masterPassword, normalizedEmail); - - var result = await LogInTwoFactorWithHashAsync(type, token, email, Crypto.HashPasswordBase64(key, masterPassword)); - - key = null; - masterPassword = null; - - return result; - } - - public async Task LogInTwoFactorWithHashAsync(TwoFactorProviderType type, string token, string email, - string masterPasswordHash) - { - if(type == TwoFactorProviderType.Email || type == TwoFactorProviderType.Authenticator) - { - token = token.Trim().Replace(" ", ""); - } - - var request = new TokenRequest - { - Email = email.Trim().ToLower(), - MasterPasswordHash = masterPasswordHash, - Token = token, - Provider = type, - Remember = false - }; - - var response = await ApiService.Instance.PostTokenAsync(request); - - if(!response.Succeeded) - { - var result = new LoginResult(); - result.Success = false; - result.ErrorMessage = response.Errors.FirstOrDefault()?.Message; - return result; - } - - return await ProcessLogInSuccessAsync(response.Result); - } - - private async Task ProcessLogInSuccessAsync(TokenResponse response) - { - TokenService.Instance.AccessToken = response.AccessToken; - TokenService.Instance.RefreshToken = response.RefreshToken; - - var result = new LoginResult(); - - var profile = await ApiService.Instance.GetProfileAsync(); - if(profile.Succeeded) - { - var adminOrgs = profile.Result.Organizations.Where(o => - o.Status == OrganizationUserStatusType.Confirmed && - o.Type != OrganizationUserType.User); - if(!adminOrgs.Any()) - { - LogOut(); - result.Success = false; - result.ErrorMessage = "You are not an admin of any organizations."; - return result; - } - - result.Organizations = adminOrgs.Select(o => new Organization(o)).ToList(); - if(result.Organizations.Count == 1) - { - SettingsService.Instance.Organization = new Organization(adminOrgs.First()); - } - - result.Success = true; - return result; - } - else - { - LogOut(); - result.Success = false; - result.ErrorMessage = "Could not load profile."; - return result; - } - } - } -} diff --git a/src/Core/Services/AzureDirectoryService.cs b/src/Core/Services/AzureDirectoryService.cs deleted file mode 100644 index 85ecab8b..00000000 --- a/src/Core/Services/AzureDirectoryService.cs +++ /dev/null @@ -1,353 +0,0 @@ -using Bit.Core.Models; -using System; -using System.Threading.Tasks; -using System.Collections.Generic; -using Microsoft.Graph; -using System.Linq; -using Bit.Core.Utilities; - -namespace Bit.Core.Services -{ - public class AzureDirectoryService : IDirectoryService - { - private static AzureDirectoryService _instance; - private static GraphServiceClient _graphClient; - - private AzureDirectoryService() - { - _graphClient = new GraphServiceClient(new AzureAuthenticationProvider()); - } - - public static IDirectoryService Instance - { - get - { - if(_instance == null) - { - _instance = new AzureDirectoryService(); - } - - return _instance; - } - } - - public async Task, List>> GetEntriesAsync(bool force = false) - { - if(!AuthService.Instance.Authenticated || !AuthService.Instance.OrganizationSet) - { - throw new ApplicationException("Not logged in or have an org set."); - } - - if(SettingsService.Instance.Server?.Azure == null) - { - throw new ApplicationException("No configuration for directory server."); - } - - if(SettingsService.Instance.Sync == null) - { - throw new ApplicationException("No configuration for sync."); - } - - List users = null; - if(SettingsService.Instance.Sync.SyncUsers) - { - users = await GetUsersAsync(force); - } - - List groups = null; - if(SettingsService.Instance.Sync.SyncGroups) - { - var filter = CreateSetFromFilter(SettingsService.Instance.Sync.GroupFilter); - groups = await GetGroupsAsync(force || (users?.Any(u => !u.Deleted && !u.Disabled) ?? false), filter); - - if(filter != null && users != null) - { - users = users.Where(u => u.Disabled || u.Deleted || - groups.Any(g => g.UserMemberExternalIds.Contains(u.ExternalId))).ToList(); - } - } - - return new Tuple, List>(groups, users); - } - - private async static Task> GetGroupsAsync(bool force, Tuple> filter) - { - if(!SettingsService.Instance.Sync.SyncGroups) - { - throw new ApplicationException("Not configured to sync groups."); - } - - if(SettingsService.Instance.Server?.Azure == null) - { - throw new ApplicationException("No configuration for directory server."); - } - - if(SettingsService.Instance.Sync == null) - { - throw new ApplicationException("No configuration for sync."); - } - - if(!AuthService.Instance.Authenticated) - { - throw new ApplicationException("Not authenticated."); - } - - var entries = new List(); - var changedGroupIds = new List(); - var getFullResults = SettingsService.Instance.GroupDeltaToken == null || force; - - try - { - var delataRequest = _graphClient.Groups.Delta().Request(); - if(!getFullResults) - { - delataRequest.QueryOptions.Add(new QueryOption("$deltatoken", SettingsService.Instance.GroupDeltaToken)); - } - - var groupsDelta = await delataRequest.GetAsync(); - while(true) - { - if(getFullResults) - { - foreach(var group in groupsDelta) - { - if(FilterOutResult(filter, group.DisplayName)) - { - continue; - } - - var entry = await BuildGroupAsync(group); - entries.Add(entry); - } - } - else - { - changedGroupIds.AddRange(groupsDelta.Select(g => g.Id)); - } - - if(groupsDelta.NextPageRequest == null) - { - object deltaLink; - if(groupsDelta.AdditionalData.TryGetValue("@odata.deltaLink", out deltaLink)) - { - var deltaUriQuery = new Uri(deltaLink.ToString()).ParseQueryString(); - if(deltaUriQuery["$deltatoken"] != null) - { - SettingsService.Instance.GroupDeltaToken = deltaUriQuery["$deltatoken"]; - } - } - break; - } - else - { - groupsDelta = await groupsDelta.NextPageRequest.GetAsync(); - } - } - } - catch { } - - if(getFullResults || !changedGroupIds.Any()) - { - return entries; - } - - var groups = await _graphClient.Groups.Request().GetAsync(); - while(true) - { - foreach(var group in groups) - { - if(FilterOutResult(filter, group.DisplayName)) - { - continue; - } - - var entry = await BuildGroupAsync(group); - entries.Add(entry); - } - - if(groups.NextPageRequest == null) - { - break; - } - else - { - groups = await groups.NextPageRequest.GetAsync(); - } - } - - return entries; - } - - private async static Task BuildGroupAsync(Group group) - { - var entry = new GroupEntry - { - ReferenceId = group.Id, - ExternalId = group.Id, - Name = group.DisplayName - }; - - var members = await _graphClient.Groups[group.Id].Members.Request().Select("id").GetAsync(); - foreach(var member in members) - { - if(member is User) - { - entry.UserMemberExternalIds.Add(member.Id); - } - else if(member is Group) - { - entry.GroupMemberReferenceIds.Add(member.Id); - } - } - - return entry; - } - - private async static Task> GetUsersAsync(bool force) - { - if(!SettingsService.Instance.Sync.SyncUsers) - { - throw new ApplicationException("Not configured to sync users."); - } - - if(SettingsService.Instance.Server?.Azure == null) - { - throw new ApplicationException("No configuration for directory server."); - } - - if(SettingsService.Instance.Sync == null) - { - throw new ApplicationException("No configuration for sync."); - } - - if(!AuthService.Instance.Authenticated) - { - throw new ApplicationException("Not authenticated."); - } - - var entries = new List(); - var filter = CreateSetFromFilter(SettingsService.Instance.Sync.UserFilter); - - var userRequest = _graphClient.Users.Delta(); - IUserDeltaCollectionPage users = null; - - if(!force && SettingsService.Instance.UserDeltaToken != null) - { - try - { - var delataRequest = userRequest.Request(); - delataRequest.QueryOptions.Add(new QueryOption("$deltatoken", SettingsService.Instance.UserDeltaToken)); - users = await delataRequest.GetAsync(); - } - catch - { - users = null; - } - } - - if(users == null) - { - users = await userRequest.Request().GetAsync(); - } - - while(true) - { - foreach(var user in users) - { - var entry = new UserEntry - { - ReferenceId = user.Id, - ExternalId = user.Id, - Email = user.Mail ?? user.UserPrincipalName, - Disabled = !user.AccountEnabled.GetValueOrDefault(true) - }; - - if(FilterOutResult(filter, entry.Email)) - { - continue; - } - - if(user.AdditionalData.TryGetValue("@removed", out object deleted) && deleted.ToString().Contains("changed")) - { - entry.Deleted = true; - } - else if(!entry.Disabled && (entry?.Email?.Contains("#") ?? true)) - { - continue; - } - - entries.Add(entry); - } - - if(users.NextPageRequest == null) - { - if(users.AdditionalData.TryGetValue("@odata.deltaLink", out object deltaLink)) - { - var deltaUriQuery = new Uri(deltaLink.ToString()).ParseQueryString(); - if(deltaUriQuery["$deltatoken"] != null) - { - SettingsService.Instance.UserDeltaToken = deltaUriQuery["$deltatoken"]; - } - } - break; - } - else - { - users = await users.NextPageRequest.GetAsync(); - } - } - - return entries; - } - - private static Tuple> CreateSetFromFilter(string filter) - { - if(string.IsNullOrWhiteSpace(filter)) - { - return null; - } - - var parts = filter.Split(':'); - if(parts.Length != 2) - { - return null; - } - - var exclude = true; - if(string.Equals(parts[0].Trim(), "include", StringComparison.InvariantCultureIgnoreCase)) - { - exclude = false; - } - else if(string.Equals(parts[0].Trim(), "exclude", StringComparison.InvariantCultureIgnoreCase)) - { - exclude = true; - } - else - { - return null; - } - - var list = new HashSet(parts[1].Split(',').Select(p => p.Trim())); - return new Tuple>(exclude, list); - } - - private static bool FilterOutResult(Tuple> filter, string result) - { - if(filter != null) - { - // excluded - if(filter.Item1 && filter.Item2.Contains(result, StringComparer.InvariantCultureIgnoreCase)) - { - return true; - } - // included - else if(!filter.Item1 && !filter.Item2.Contains(result, StringComparer.InvariantCultureIgnoreCase)) - { - return true; - } - } - - return false; - } - } -} diff --git a/src/Core/Services/ControllerService.cs b/src/Core/Services/ControllerService.cs deleted file mode 100644 index 84efeb67..00000000 --- a/src/Core/Services/ControllerService.cs +++ /dev/null @@ -1,95 +0,0 @@ -using Bit.Core.Utilities; -#if NET461 -using System.ServiceProcess; -#endif - -namespace Bit.Core.Services -{ - public class ControllerService - { - private static ControllerService _instance; - - private ControllerService() - { -#if NET461 - Controller = new ServiceController(Constants.ProgramName); -#endif - } - - public static ControllerService Instance - { - get - { - if(_instance == null) - { - _instance = new ControllerService(); - } - - return _instance; - } - } - -#if NET461 - public ServiceController Controller { get; private set; } - public ServiceControllerStatus Status - { - get - { - Controller.Refresh(); - return Controller.Status; - } - } - public bool Running => Status == ServiceControllerStatus.Running; - public bool Paused => Status == ServiceControllerStatus.Paused; - public bool Stopped => Status == ServiceControllerStatus.Stopped; - public bool Pending => - Status == ServiceControllerStatus.ContinuePending || - Status == ServiceControllerStatus.PausePending || - Status == ServiceControllerStatus.StartPending || - Status == ServiceControllerStatus.StopPending; -#endif - public string StatusString - { - get - { -#if NET461 - return Controller == null ? "Unavailable" : Status.ToString(); -#else - return "Unavailable"; -#endif - } - } - - - public bool Start() - { -#if NET461 - if(Controller == null || !Stopped) - { - return false; - } - - Controller.Start(); - return true; -#else - throw new System.Exception("Controller unavailable."); -#endif - } - - public bool Stop() - { -#if NET461 - if(Controller == null || !Controller.CanStop) - { - return false; - } - - Controller.Stop(); - - return true; -#else - throw new System.Exception("Controller unavailable."); -#endif - } - } -} diff --git a/src/Core/Services/GSuiteDirectoryService.cs b/src/Core/Services/GSuiteDirectoryService.cs deleted file mode 100644 index c9286178..00000000 --- a/src/Core/Services/GSuiteDirectoryService.cs +++ /dev/null @@ -1,306 +0,0 @@ -using Bit.Core.Models; -using System; -using System.Threading.Tasks; -using System.Collections.Generic; -using Google.Apis.Admin.Directory.directory_v1; -using Google.Apis.Services; -using Google.Apis.Auth.OAuth2; -using System.IO; -using Bit.Core.Utilities; -using System.Linq; -using Google.Apis.Admin.Directory.directory_v1.Data; -using Google.Apis.Requests; - -namespace Bit.Core.Services -{ - public class GSuiteDirectoryService : IDirectoryService - { - private static GSuiteDirectoryService _instance; - private static DirectoryService _service; - - private GSuiteDirectoryService() - { - ICredential creds; - - var secretFilePath = Path.Combine(Constants.BaseStoragePath, SettingsService.Instance.Server.GSuite.SecretFile); - using(var stream = new FileStream(secretFilePath, FileMode.Open, FileAccess.Read)) - { - var scopes = new List - { - DirectoryService.Scope.AdminDirectoryUserReadonly, - DirectoryService.Scope.AdminDirectoryGroupReadonly, - DirectoryService.Scope.AdminDirectoryGroupMemberReadonly - }; - - creds = GoogleCredential.FromStream(stream) - .CreateScoped(scopes) - .CreateWithUser(SettingsService.Instance.Server.GSuite.AdminUser); - } - - _service = new DirectoryService(new BaseClientService.Initializer - { - HttpClientInitializer = creds, - ApplicationName = Constants.ProgramName - }); - } - - public static IDirectoryService Instance - { - get - { - if(_instance == null) - { - _instance = new GSuiteDirectoryService(); - } - - return _instance; - } - } - - public async Task, List>> GetEntriesAsync(bool force = false) - { - if(!AuthService.Instance.Authenticated || !AuthService.Instance.OrganizationSet) - { - throw new ApplicationException("Not logged in or have an org set."); - } - - if(SettingsService.Instance.Server?.GSuite == null) - { - throw new ApplicationException("No configuration for directory server."); - } - - if(SettingsService.Instance.Sync == null) - { - throw new ApplicationException("No configuration for sync."); - } - - List users = null; - if(SettingsService.Instance.Sync.SyncUsers) - { - users = await GetUsersAsync(force); - } - - List groups = null; - if(SettingsService.Instance.Sync.SyncGroups) - { - groups = await GetGroupsAsync(force || (users?.Any(u => !u.Deleted && !u.Disabled) ?? false)); - } - - return new Tuple, List>(groups, users); - } - - private Task> GetGroupsAsync(bool force) - { - var entries = new List(); - - var request = _service.Groups.List(); - request.Domain = SettingsService.Instance.Server.GSuite.Domain; - request.Customer = SettingsService.Instance.Server.GSuite.Customer; - - var pageStreamer = new PageStreamer( - (req, token) => req.PageToken = token, - res => res.NextPageToken, - res => res.GroupsValue); - - var filter = CreateSetFromFilter(SettingsService.Instance.Sync.GroupFilter); - foreach(var group in pageStreamer.Fetch(request)) - { - if(FilterOutResult(filter, group.Name)) - { - continue; - } - - var entry = BuildGroup(group); - entries.Add(entry); - } - - return Task.FromResult(entries); - } - - private static GroupEntry BuildGroup(Group group) - { - var entry = new GroupEntry - { - ReferenceId = group.Id, - ExternalId = group.Id, - Name = group.Name - }; - - var memberRequest = _service.Members.List(group.Id); - var pageStreamer = new PageStreamer( - (req, token) => req.PageToken = token, - res => res.NextPageToken, - res => res.MembersValue); - - foreach(var member in pageStreamer.Fetch(memberRequest)) - { - if(!member.Role.Equals("member", StringComparison.InvariantCultureIgnoreCase) || - !member.Status.Equals("active", StringComparison.InvariantCultureIgnoreCase)) - { - continue; - } - - if(member.Type.Equals("user", StringComparison.InvariantCultureIgnoreCase)) - { - entry.UserMemberExternalIds.Add(member.Id); - } - else if(member.Type.Equals("group", StringComparison.InvariantCultureIgnoreCase)) - { - entry.GroupMemberReferenceIds.Add(member.Id); - } - } - - return entry; - } - - private Task> GetUsersAsync(bool force) - { - var entries = new List(); - var query = CreateGSuiteQueryFromFilter(SettingsService.Instance.Sync.UserFilter); - - var request = _service.Users.List(); - request.Domain = SettingsService.Instance.Server.GSuite.Domain; - request.Customer = SettingsService.Instance.Server.GSuite.Customer; - request.Query = query; - - var pageStreamer = new PageStreamer( - (req, token) => req.PageToken = token, - res => res.NextPageToken, - res => res.UsersValue); - - var filter = CreateSetFromFilter(SettingsService.Instance.Sync.UserFilter); - foreach(var user in pageStreamer.Fetch(request)) - { - if(FilterOutResult(filter, user.PrimaryEmail)) - { - continue; - } - - var entry = BuildUser(user, false); - if(entry != null) - { - entries.Add(entry); - } - } - - var deletedRequest = _service.Users.List(); - deletedRequest.Domain = SettingsService.Instance.Server.GSuite.Domain; - deletedRequest.Customer = SettingsService.Instance.Server.GSuite.Customer; - deletedRequest.Query = query; - deletedRequest.ShowDeleted = "true"; - - var deletedPageStreamer = new PageStreamer( - (req, token) => req.PageToken = token, - res => res.NextPageToken, - res => res.UsersValue); - - foreach(var user in deletedPageStreamer.Fetch(deletedRequest)) - { - if(FilterOutResult(filter, user.PrimaryEmail)) - { - continue; - } - - var entry = BuildUser(user, true); - if(entry != null) - { - entries.Add(entry); - } - } - - return Task.FromResult(entries); - } - - private UserEntry BuildUser(User user, bool deleted) - { - var entry = new UserEntry - { - ReferenceId = user.Id, - ExternalId = user.Id, - Email = user.PrimaryEmail, - Disabled = user.Suspended.GetValueOrDefault(false), - Deleted = deleted, - CreationDate = user.CreationTime - }; - - if(string.IsNullOrWhiteSpace(entry.Email) && !entry.Deleted) - { - return null; - } - - return entry; - } - - private string CreateGSuiteQueryFromFilter(string filter) - { - if(string.IsNullOrWhiteSpace(filter)) - { - return null; - } - - var mainParts = filter.Split('|'); - if(mainParts.Count() < 2 || string.IsNullOrWhiteSpace(mainParts[1])) - { - return null; - } - - return mainParts[1].Trim(); - } - - private Tuple> CreateSetFromFilter(string filter) - { - if(string.IsNullOrWhiteSpace(filter)) - { - return null; - } - - var mainParts = filter.Split('|'); - if(mainParts.Count() < 1 || string.IsNullOrWhiteSpace(mainParts[0])) - { - return null; - } - - var parts = mainParts[0].Split(':'); - if(parts.Count() != 2) - { - return null; - } - - var exclude = true; - if(string.Equals(parts[0].Trim(), "include", StringComparison.InvariantCultureIgnoreCase)) - { - exclude = false; - } - else if(string.Equals(parts[0].Trim(), "exclude", StringComparison.InvariantCultureIgnoreCase)) - { - exclude = true; - } - else - { - return null; - } - - var list = new HashSet(parts[1].Split(',').Select(p => p.Trim())); - return new Tuple>(exclude, list); - } - - private bool FilterOutResult(Tuple> filter, string result) - { - if(filter != null) - { - // excluded - if(filter.Item1 && filter.Item2.Contains(result, StringComparer.InvariantCultureIgnoreCase)) - { - return true; - } - // included - else if(!filter.Item1 && !filter.Item2.Contains(result, StringComparer.InvariantCultureIgnoreCase)) - { - return true; - } - } - - return false; - } - } -} diff --git a/src/Core/Services/IDirectoryService.cs b/src/Core/Services/IDirectoryService.cs deleted file mode 100644 index f7c16338..00000000 --- a/src/Core/Services/IDirectoryService.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Bit.Core.Models; -using System; -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace Bit.Core.Services -{ - public interface IDirectoryService - { - Task, List>> GetEntriesAsync(bool force = false); - } -} diff --git a/src/Core/Services/LdapDirectoryService.cs b/src/Core/Services/LdapDirectoryService.cs deleted file mode 100644 index 59b23005..00000000 --- a/src/Core/Services/LdapDirectoryService.cs +++ /dev/null @@ -1,402 +0,0 @@ -#if NET461 -using Bit.Core.Enums; -using Bit.Core.Models; -using Bit.Core.Utilities; -using System; -using System.Collections.Generic; -using System.DirectoryServices; -using System.Linq; -using System.Net; -using System.Threading.Tasks; - -namespace Bit.Core.Services -{ - public class LdapDirectoryService : IDirectoryService - { - private static LdapDirectoryService _instance; - - private LdapDirectoryService() { } - - public static IDirectoryService Instance - { - get - { - if(_instance == null) - { - _instance = new LdapDirectoryService(); - } - - return _instance; - } - } - - public async Task, List>> GetEntriesAsync(bool force = false) - { - if(!AuthService.Instance.Authenticated || !AuthService.Instance.OrganizationSet) - { - throw new ApplicationException("Not logged in or have an org set."); - } - - if(SettingsService.Instance.Server?.Ldap == null) - { - throw new ApplicationException("No configuration for directory server."); - } - - if(SettingsService.Instance.Sync == null) - { - throw new ApplicationException("No configuration for sync."); - } - - List users = null; - if(SettingsService.Instance.Sync.SyncUsers) - { - users = await GetUsersAsync(force); - } - - List groups = null; - if(SettingsService.Instance.Sync.SyncGroups) - { - groups = await GetGroupsAsync(force || (users?.Any(u => !u.Deleted && !u.Disabled) ?? false)); - } - - return new Tuple, List>(groups, users); - } - - private static Task> GetGroupsAsync(bool force = false) - { - if(!SettingsService.Instance.Sync.SyncGroups) - { - throw new ApplicationException("Not configured to sync groups."); - } - - if(SettingsService.Instance.Server?.Ldap == null) - { - throw new ApplicationException("No configuration for directory server."); - } - - if(SettingsService.Instance.Sync == null) - { - throw new ApplicationException("No configuration for sync."); - } - - if(!AuthService.Instance.Authenticated) - { - throw new ApplicationException("Not authenticated."); - } - - var groupEntry = SettingsService.Instance.Server.Ldap.GetGroupDirectoryEntry(); - - var originalFilter = BuildBaseFilter(SettingsService.Instance.Sync.Ldap.GroupObjectClass, - SettingsService.Instance.Sync.GroupFilter); - - var filter = originalFilter; - var revisionFilter = BuildRevisionFilter(filter, force, SettingsService.Instance.LastGroupSyncDate); - var searchSinceRevision = filter != revisionFilter; - filter = revisionFilter; - - Console.WriteLine("Group search: {0} => {1}", groupEntry.Path, filter); - var searcher = new DirectorySearcher(groupEntry, filter); - var result = searcher.FindAll(); - - var initialSearchGroupIds = new List(); - foreach(SearchResult item in result) - { - initialSearchGroupIds.Add(DNFromPath(item.Path)); - } - - if(searchSinceRevision && !initialSearchGroupIds.Any()) - { - return Task.FromResult(new List()); - } - else if(searchSinceRevision) - { - searcher = new DirectorySearcher(groupEntry, originalFilter); - result = searcher.FindAll(); - } - - var userEntry = SettingsService.Instance.Server.Ldap.GetUserDirectoryEntry(); - var userFilter = BuildBaseFilter(SettingsService.Instance.Sync.Ldap.UserObjectClass, - SettingsService.Instance.Sync.UserFilter); - var userSearcher = new DirectorySearcher(userEntry, userFilter); - var userResult = userSearcher.FindAll(); - - var userIdsDict = MakeIdIndex(userResult); - - var groups = new List(); - foreach(SearchResult item in result) - { - var group = BuildGroup(item, userIdsDict); - if(group == null) - { - continue; - } - - groups.Add(group); - } - - return Task.FromResult(groups); - } - - private static Dictionary MakeIdIndex(SearchResultCollection result) - { - var dict = new Dictionary(); - foreach(SearchResult item in result) - { - var referenceId = DNFromPath(item.Path); - var externalId = referenceId; - - if(item.Properties.Contains("objectGUID") && item.Properties["objectGUID"].Count > 0) - { - externalId = item.Properties["objectGUID"][0].FromGuidToString(); - } - - dict.Add(referenceId, externalId); - } - return dict; - } - - private static GroupEntry BuildGroup(SearchResult item, Dictionary userIndex) - { - var group = new GroupEntry - { - ReferenceId = DNFromPath(item.Path) - }; - - if(group.ReferenceId == null) - { - return null; - } - - // External Id - if(item.Properties.Contains("objectGUID") && item.Properties["objectGUID"].Count > 0) - { - group.ExternalId = item.Properties["objectGUID"][0].FromGuidToString(); - } - else - { - group.ExternalId = group.ReferenceId; - } - - // Name - if(item.Properties.Contains(SettingsService.Instance.Sync.Ldap.GroupNameAttribute) && - item.Properties[SettingsService.Instance.Sync.Ldap.GroupNameAttribute].Count > 0) - { - group.Name = item.Properties[SettingsService.Instance.Sync.Ldap.GroupNameAttribute][0].ToString(); - } - else if(item.Properties.Contains("cn") && item.Properties["cn"].Count > 0) - { - group.Name = item.Properties["cn"][0].ToString(); - } - else - { - return null; - } - - // Dates - group.CreationDate = item.Properties.ParseDateTime(SettingsService.Instance.Sync.Ldap.CreationDateAttribute); - group.RevisionDate = item.Properties.ParseDateTime(SettingsService.Instance.Sync.Ldap.RevisionDateAttribute); - - // Members - if(item.Properties.Contains(SettingsService.Instance.Sync.Ldap.MemberAttribute) && - item.Properties[SettingsService.Instance.Sync.Ldap.MemberAttribute].Count > 0) - { - foreach(var member in item.Properties[SettingsService.Instance.Sync.Ldap.MemberAttribute]) - { - var memberDn = member.ToString(); - if(userIndex.ContainsKey(memberDn) && !group.UserMemberExternalIds.Contains(userIndex[memberDn])) - { - group.UserMemberExternalIds.Add(userIndex[memberDn]); - } - else if(!group.GroupMemberReferenceIds.Contains(memberDn)) - { - group.GroupMemberReferenceIds.Add(memberDn); - } - } - } - - return group; - } - - private static Task> GetUsersAsync(bool force = false) - { - if(!SettingsService.Instance.Sync.SyncUsers) - { - throw new ApplicationException("Not configured to sync users."); - } - - if(SettingsService.Instance.Server?.Ldap == null) - { - throw new ApplicationException("No configuration for directory server."); - } - - if(SettingsService.Instance.Sync == null) - { - throw new ApplicationException("No configuration for sync."); - } - - if(!AuthService.Instance.Authenticated) - { - throw new ApplicationException("Not authenticated."); - } - - var userEntry = SettingsService.Instance.Server.Ldap.GetUserDirectoryEntry(); - var filter = BuildBaseFilter(SettingsService.Instance.Sync.Ldap.UserObjectClass, - SettingsService.Instance.Sync.UserFilter); - filter = BuildRevisionFilter(filter, force, SettingsService.Instance.LastUserSyncDate); - - Console.WriteLine("User search: {0} => {1}", userEntry.Path, filter); - var searcher = new DirectorySearcher(userEntry, filter); - var result = searcher.FindAll(); - - var users = new List(); - foreach(SearchResult item in result) - { - var user = BuildUser(item, false); - if(user == null) - { - continue; - } - - users.Add(user); - } - - // Deleted users - if(SettingsService.Instance.Server.Type == DirectoryType.ActiveDirectory) - { - var deletedEntry = SettingsService.Instance.Server.Ldap.GetBasePathDirectoryEntry(); - var deletedFilter = BuildBaseFilter(SettingsService.Instance.Sync.Ldap.UserObjectClass, "(isDeleted=TRUE)"); - deletedFilter = BuildRevisionFilter(deletedFilter, force, SettingsService.Instance.LastUserSyncDate); - - var deletedSearcher = new DirectorySearcher(deletedEntry, deletedFilter); - deletedSearcher.Tombstone = true; - var deletedResult = deletedSearcher.FindAll(); - foreach(SearchResult item in deletedResult) - { - var user = BuildUser(item, true); - if(user == null) - { - continue; - } - - users.Add(user); - } - } - - return Task.FromResult(users); - } - - private static string BuildBaseFilter(string objectClass, string subFilter) - { - var filter = BuildObjectClassFilter(objectClass); - if(!string.IsNullOrWhiteSpace(subFilter)) - { - filter = string.Format("(&{0}{1})", filter, subFilter); - } - - return filter; - } - - private static string BuildObjectClassFilter(string objectClass) - { - return string.Format("(&(objectClass={0}))", objectClass); - } - - private static string BuildRevisionFilter(string baseFilter, bool force, DateTime? lastRevisionDate) - { - if(!force && lastRevisionDate.HasValue && - !string.IsNullOrWhiteSpace(SettingsService.Instance.Sync.Ldap.RevisionDateAttribute)) - { - baseFilter = string.Format("(&{0}({1}>={2}))", - baseFilter, - SettingsService.Instance.Sync.Ldap.RevisionDateAttribute, - lastRevisionDate.Value.ToGeneralizedTimeUTC()); - } - - return baseFilter; - } - - private static UserEntry BuildUser(SearchResult item, bool deleted) - { - var user = new UserEntry - { - ReferenceId = DNFromPath(item.Path), - Deleted = deleted - }; - - if(user.ReferenceId == null) - { - return null; - } - - // External Id - if(item.Properties.Contains("objectGUID") && item.Properties["objectGUID"].Count > 0) - { - user.ExternalId = item.Properties["objectGUID"][0].FromGuidToString(); - } - else - { - user.ExternalId = user.ReferenceId; - } - - user.Disabled = EntryDisabled(item); - - // Email - if(item.Properties.Contains(SettingsService.Instance.Sync.Ldap.UserEmailAttribute) && - item.Properties[SettingsService.Instance.Sync.Ldap.UserEmailAttribute].Count > 0) - { - user.Email = item.Properties[SettingsService.Instance.Sync.Ldap.UserEmailAttribute][0] - .ToString() - .ToLowerInvariant(); - } - - if(string.IsNullOrWhiteSpace(user.Email) && SettingsService.Instance.Sync.Ldap.EmailPrefixSuffix && - item.Properties.Contains(SettingsService.Instance.Sync.Ldap.UserEmailPrefixAttribute) && - item.Properties[SettingsService.Instance.Sync.Ldap.UserEmailPrefixAttribute].Count > 0 && - !string.IsNullOrWhiteSpace(SettingsService.Instance.Sync.Ldap.UserEmailSuffix)) - { - user.Email = string.Concat( - item.Properties[SettingsService.Instance.Sync.Ldap.UserEmailPrefixAttribute][0].ToString(), - SettingsService.Instance.Sync.Ldap.UserEmailSuffix).ToLowerInvariant(); - } - - if(string.IsNullOrWhiteSpace(user.Email) && !user.Deleted) - { - return null; - } - - // Dates - user.CreationDate = item.Properties.ParseDateTime(SettingsService.Instance.Sync.Ldap.CreationDateAttribute); - user.RevisionDate = item.Properties.ParseDateTime(SettingsService.Instance.Sync.Ldap.RevisionDateAttribute); - - return user; - } - - private static bool EntryDisabled(SearchResult item) - { - if(!item.Properties.Contains("userAccountControl") || item.Properties["userAccountControl"].Count == 0) - { - return false; - } - - UserAccountControl control; - if(!Enum.TryParse(item.Properties["userAccountControl"][0].ToString(), out control)) - { - return false; - } - - return (control & UserAccountControl.AccountDisabled) == UserAccountControl.AccountDisabled; - } - - private static string DNFromPath(string path) - { - var dn = new Uri(path).Segments?.LastOrDefault(); - if(dn == null) - { - return null; - } - - return WebUtility.UrlDecode(dn); - } - } -} -#endif diff --git a/src/Core/Services/SettingsService.cs b/src/Core/Services/SettingsService.cs deleted file mode 100644 index b1366430..00000000 --- a/src/Core/Services/SettingsService.cs +++ /dev/null @@ -1,266 +0,0 @@ -using Bit.Core.Models; -using Bit.Core.Utilities; -using Newtonsoft.Json; -using System; -using System.IO; -using System.Text; - -namespace Bit.Core.Services -{ - public class SettingsService - { - private static SettingsService _instance; - private static object _locker = new object(); - - private SettingsModel _settings; - - private SettingsService() { } - - public static SettingsService Instance - { - get - { - if(_instance == null) - { - _instance = new SettingsService(); - } - - return _instance; - } - } - - private SettingsModel Settings - { - get - { - var filePath = $"{Constants.BaseStoragePath}\\settings.json"; - if(_settings == null && File.Exists(filePath)) - { - var serializer = new JsonSerializer(); - using(var s = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)) - using(var sr = new StreamReader(s, Encoding.UTF8)) - using(var jsonTextReader = new JsonTextReader(sr)) - { - _settings = serializer.Deserialize(jsonTextReader); - } - - return _settings; - } - - InitSettings(); - return _settings; - } - } - - private void SaveSettings() - { - lock(_locker) - { - if(!Directory.Exists(Constants.BaseStoragePath)) - { - Directory.CreateDirectory(Constants.BaseStoragePath); - } - - var filePath = $"{Constants.BaseStoragePath}\\settings.json"; - using(var s = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.Read)) - using(var sw = new StreamWriter(s, Encoding.UTF8)) - { - var json = JsonConvert.SerializeObject(_settings, Formatting.Indented); - sw.Write(json); - } - } - } - - private void InitSettings() - { - if(_settings == null) - { - _settings = new SettingsModel(); - } - } - - public string ApiBaseUrl - { - get - { - return Settings.ApiBaseUrl; - } - set - { - InitSettings(); - _settings.ApiBaseUrl = value; - SaveSettings(); - } - } - - public string IdentityBaseUrl - { - get - { - return Settings.IdentityBaseUrl; - } - set - { - InitSettings(); - _settings.IdentityBaseUrl = value; - SaveSettings(); - } - } - - public EncryptedData AccessToken - { - get - { - return Settings.AccessToken; - } - set - { - InitSettings(); - _settings.AccessToken = value; - SaveSettings(); - } - } - - public EncryptedData RefreshToken - { - get - { - return Settings.RefreshToken; - } - set - { - InitSettings(); - _settings.RefreshToken = value; - SaveSettings(); - } - } - - public Organization Organization - { - get - { - return Settings.Organization; - } - set - { - InitSettings(); - _settings.Organization = value; - SaveSettings(); - } - } - - public ServerConfiguration Server - { - get - { - return Settings.Server; - } - set - { - InitSettings(); - _settings.Server = value; - SaveSettings(); - } - } - - public SyncConfiguration Sync - { - get - { - return Settings.Sync; - } - set - { - InitSettings(); - _settings.Sync = value; - SaveSettings(); - } - } - - public DateTime? LastGroupSyncDate - { - get - { - return Settings.LastGroupSyncDate; - } - set - { - InitSettings(); - _settings.LastGroupSyncDate = value; - SaveSettings(); - } - } - - public DateTime? LastUserSyncDate - { - get - { - return Settings.LastUserSyncDate; - } - set - { - InitSettings(); - _settings.LastUserSyncDate = value; - SaveSettings(); - } - } - - public string GroupDeltaToken - { - get - { - return Settings.GroupDeltaToken; - } - set - { - InitSettings(); - _settings.GroupDeltaToken = value; - SaveSettings(); - } - } - - public string UserDeltaToken - { - get - { - return Settings.UserDeltaToken; - } - set - { - InitSettings(); - _settings.UserDeltaToken = value; - SaveSettings(); - } - } - - public string LastSyncHash - { - get - { - return Settings.LastSyncHash; - } - set - { - InitSettings(); - _settings.LastSyncHash = value; - SaveSettings(); - } - } - - public class SettingsModel - { - public string ApiBaseUrl { get; set; } = "https://api.bitwarden.com"; - public string IdentityBaseUrl { get; set; } = "https://identity.bitwarden.com"; - public EncryptedData AccessToken { get; set; } - public EncryptedData RefreshToken { get; set; } - public ServerConfiguration Server { get; set; } = new ServerConfiguration(); - public SyncConfiguration Sync { get; set; } = new SyncConfiguration(Enums.DirectoryType.ActiveDirectory); - public Organization Organization { get; set; } = new Organization(); - public DateTime? LastGroupSyncDate { get; set; } - public DateTime? LastUserSyncDate { get; set; } - public string GroupDeltaToken { get; set; } - public string UserDeltaToken { get; set; } - public string LastSyncHash { get; set; } - } - } -} diff --git a/src/Core/Services/TokenService.cs b/src/Core/Services/TokenService.cs deleted file mode 100644 index a2cf0ee4..00000000 --- a/src/Core/Services/TokenService.cs +++ /dev/null @@ -1,167 +0,0 @@ -using Bit.Core.Models; -using Newtonsoft.Json.Linq; -using System; -using System.Text; - -namespace Bit.Core.Services -{ - public class TokenService - { - private static TokenService _instance; - private static readonly DateTime _epoc = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); - - private string _accessToken; - private dynamic _decodedAccessToken; - - private TokenService() { } - - public static TokenService Instance - { - get - { - if(_instance == null) - { - _instance = new TokenService(); - } - - return _instance; - } - } - - public string AccessToken - { - get - { - if(_accessToken != null) - { - return _accessToken; - } - - var encBytes = SettingsService.Instance.AccessToken; - if(encBytes?.Value != null) - { - _accessToken = Encoding.ASCII.GetString(encBytes.Decrypt()); - } - - return _accessToken; - } - set - { - _accessToken = value; - if(_accessToken == null) - { - SettingsService.Instance.AccessToken = null; - } - else - { - var bytes = Encoding.ASCII.GetBytes(_accessToken); - SettingsService.Instance.AccessToken = new EncryptedData(bytes); - bytes = null; - } - } - } - - public DateTime AccessTokenExpiration - { - get - { - var decoded = DecodeAccessToken(); - if(decoded?["exp"] == null) - { - throw new InvalidOperationException("No exp in token."); - } - - return _epoc.AddSeconds(Convert.ToDouble(decoded["exp"].Value())); - } - } - - public bool AccessTokenExpired => DateTime.UtcNow < AccessTokenExpiration; - public TimeSpan AccessTokenTimeRemaining => AccessTokenExpiration - DateTime.UtcNow; - public bool AccessTokenNeedsRefresh => AccessTokenTimeRemaining.TotalMinutes < 5; - public string AccessTokenUserId => DecodeAccessToken()?["sub"].Value(); - public string AccessTokenEmail => DecodeAccessToken()?["email"].Value(); - public string AccessTokenName => DecodeAccessToken()?["name"].Value(); - - public string RefreshToken - { - get - { - var encData = SettingsService.Instance.RefreshToken; - if(encData != null) - { - return Encoding.ASCII.GetString(encData.Decrypt()); - } - - return null; - } - set - { - if(value == null) - { - SettingsService.Instance.RefreshToken = null; - } - else - { - var bytes = Encoding.ASCII.GetBytes(value); - SettingsService.Instance.RefreshToken = new EncryptedData(bytes); - bytes = null; - } - } - } - - public JObject DecodeAccessToken() - { - if(_decodedAccessToken != null) - { - return _decodedAccessToken; - } - - if(AccessToken == null) - { - throw new InvalidOperationException($"{nameof(AccessToken)} not found."); - } - - var parts = AccessToken.Split('.'); - if(parts.Length != 3) - { - throw new InvalidOperationException($"{nameof(AccessToken)} must have 3 parts"); - } - - var decodedBytes = Base64UrlDecode(parts[1]); - if(decodedBytes == null || decodedBytes.Length < 1) - { - throw new InvalidOperationException($"{nameof(AccessToken)} must have 3 parts"); - } - - _decodedAccessToken = JObject.Parse(Encoding.UTF8.GetString(decodedBytes, 0, decodedBytes.Length)); - return _decodedAccessToken; - } - - private static byte[] Base64UrlDecode(string input) - { - var output = input; - // 62nd char of encoding - output = output.Replace('-', '+'); - // 63rd char of encoding - output = output.Replace('_', '/'); - // Pad with trailing '='s - switch(output.Length % 4) - { - case 0: - // No pad chars in this case - break; - case 2: - // Two pad chars - output += "=="; break; - case 3: - // One pad char - output += "="; break; - default: - throw new InvalidOperationException("Illegal base64url string!"); - } - - // Standard base64 decoder - return Convert.FromBase64String(output); - } - } -} diff --git a/src/Core/Utilities/AzureAuthenticationProvider.cs b/src/Core/Utilities/AzureAuthenticationProvider.cs deleted file mode 100644 index 07b30227..00000000 --- a/src/Core/Utilities/AzureAuthenticationProvider.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Bit.Core.Services; -using Microsoft.Graph; -using Microsoft.IdentityModel.Clients.ActiveDirectory; -using System; -using System.Net.Http; -using System.Threading.Tasks; - -namespace Bit.Core.Utilities -{ - public class AzureAuthenticationProvider : IAuthenticationProvider - { - public async Task AuthenticateRequestAsync(HttpRequestMessage request) - { - if(SettingsService.Instance.Server?.Azure == null) - { - throw new ApplicationException("No server configuration."); - } - - var authContext = new AuthenticationContext( - $"https://login.windows.net/{SettingsService.Instance.Server.Azure.Tenant}/oauth2/token"); - var secret = SettingsService.Instance.Server.Azure.Secret.DecryptToString(); - var creds = new ClientCredential(SettingsService.Instance.Server.Azure.Id, secret); - var authResult = await authContext.AcquireTokenAsync("https://graph.microsoft.com/", creds); - request.Headers.Add("Authorization", $"Bearer {authResult.AccessToken}"); - } - } -} diff --git a/src/Core/Utilities/Constants.cs b/src/Core/Utilities/Constants.cs deleted file mode 100644 index 3f7d0ee4..00000000 --- a/src/Core/Utilities/Constants.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Bit.Core.Utilities -{ - public static class Constants - { - public static string BaseStoragePath = string.Concat( - Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), - "\\Bitwarden\\Directory Connector"); - - public const string ProgramName = "Bitwarden Directory Connector"; - } -} diff --git a/src/Core/Utilities/Crypto.cs b/src/Core/Utilities/Crypto.cs deleted file mode 100644 index b2c2ff06..00000000 --- a/src/Core/Utilities/Crypto.cs +++ /dev/null @@ -1,80 +0,0 @@ -using Org.BouncyCastle.Crypto.Digests; -using Org.BouncyCastle.Crypto.Generators; -using Org.BouncyCastle.Crypto.Parameters; -using System; -using System.Text; - -namespace Bit.Core.Utilities -{ - public static class Crypto - { - public static byte[] MakeKeyFromPassword(string password, string salt) - { - if(password == null) - { - throw new ArgumentNullException(nameof(password)); - } - - if(salt == null) - { - throw new ArgumentNullException(nameof(salt)); - } - - var passwordBytes = Encoding.UTF8.GetBytes(password); - var saltBytes = Encoding.UTF8.GetBytes(salt); - - var keyBytes = DeriveKey(passwordBytes, saltBytes, 5000); - - password = null; - passwordBytes = null; - - return keyBytes; - } - - public static string MakeKeyFromPasswordBase64(string password, string salt) - { - var key = MakeKeyFromPassword(password, salt); - password = null; - return Convert.ToBase64String(key); - } - - public static byte[] HashPassword(byte[] key, string password) - { - if(key == null) - { - throw new ArgumentNullException(nameof(key)); - } - - if(password == null) - { - throw new ArgumentNullException(nameof(password)); - } - - var passwordBytes = Encoding.UTF8.GetBytes(password); - - var hashBytes = DeriveKey(key, passwordBytes, 1); - - password = null; - key = null; - - return hashBytes; - } - - public static string HashPasswordBase64(byte[] key, string password) - { - var hash = HashPassword(key, password); - password = null; - key = null; - return Convert.ToBase64String(hash); - } - - private static byte[] DeriveKey(byte[] password, byte[] salt, int rounds) - { - var generator = new Pkcs5S2ParametersGenerator(new Sha256Digest()); - generator.Init(password, salt, rounds); - var key = ((KeyParameter)generator.GenerateDerivedMacParameters(256)).GetKey(); - password = null; - return key; - } - } -} diff --git a/src/Core/Utilities/Extensions.cs b/src/Core/Utilities/Extensions.cs deleted file mode 100644 index 199d0488..00000000 --- a/src/Core/Utilities/Extensions.cs +++ /dev/null @@ -1,69 +0,0 @@ -using System; -using System.Collections.Specialized; -#if NET461 -using System.DirectoryServices; -#endif -using System.Globalization; - -namespace Bit.Core.Utilities -{ - public static class Extensions - { - private const string GeneralizedTimeFormat = "yyyyMMddHHmmss.f'Z'"; - - public static DateTime ToDateTime(this string generalizedTimeString) - { - return DateTime.ParseExact(generalizedTimeString, GeneralizedTimeFormat, CultureInfo.InvariantCulture); - } - - public static string ToGeneralizedTimeUTC(this DateTime date) - { - return date.ToString("yyyyMMddHHmmss.f'Z'"); - } - -#if NET461 - public static DateTime? ParseDateTime(this ResultPropertyCollection collection, string dateKey) - { - DateTime date; - if(collection.Contains(dateKey) && collection[dateKey].Count > 0 && - DateTime.TryParse(collection[dateKey][0].ToString(), out date)) - { - return date; - } - - return null; - } -#endif - - public static NameValueCollection ParseQueryString(this Uri uri) - { - var queryParameters = new NameValueCollection(); - var querySegments = uri.Query.Split('&'); - foreach(var segment in querySegments) - { - var parts = segment.Split('='); - if(parts.Length > 0) - { - var key = parts[0].Trim(new char[] { '?', ' ' }); - var val = parts[1].Trim(); - queryParameters.Add(key, val); - } - } - - return queryParameters; - } - - public static string FromGuidToString(this object property) - { - var propBytes = property as byte[]; - if(propBytes != null) - { - return new Guid(propBytes).ToString(); - } - else - { - return property.ToString(); - } - } - } -} diff --git a/src/Core/Utilities/Helpers.cs b/src/Core/Utilities/Helpers.cs deleted file mode 100644 index 609bb0a7..00000000 --- a/src/Core/Utilities/Helpers.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Security.Principal; - -namespace Bit.Core.Utilities -{ - public static class Helpers - { - public static bool IsAdministrator() - { -#if NET461 - var identity = WindowsIdentity.GetCurrent(); - var principal = new WindowsPrincipal(identity); - return principal.IsInRole(WindowsBuiltInRole.Administrator); -#else - return false; -#endif - } - } -} diff --git a/src/Core/Utilities/Sync.cs b/src/Core/Utilities/Sync.cs deleted file mode 100644 index 894fa160..00000000 --- a/src/Core/Utilities/Sync.cs +++ /dev/null @@ -1,176 +0,0 @@ -using Bit.Core.Models; -using Bit.Core.Services; -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Security.Cryptography; -using System.Text; -using System.Threading.Tasks; - -namespace Bit.Core.Utilities -{ - public static class Sync - { - public static async Task SyncAllAsync(bool force = false, bool sendToServer = true) - { - var startingGroupDelta = SettingsService.Instance.GroupDeltaToken; - var startingUserDelta = SettingsService.Instance.UserDeltaToken; - - try - { - var now = DateTime.UtcNow; - var entriesResult = await GetDirectoryService().GetEntriesAsync(force); - var groups = entriesResult.Item1; - var users = entriesResult.Item2; - - if(groups?.Any() ?? false) - { - FlattenUsersToGroups(groups, null, groups); - } - - if(!sendToServer) - { - RestoreDeltas(startingGroupDelta, startingUserDelta); - } - - if(!sendToServer || ((groups?.Count ?? 0) == 0 && (users?.Count ?? 0) == 0)) - { - return new SyncResult - { - Success = true, - Groups = groups, - Users = users - }; - } - - var request = new ImportRequest(groups, users); - var json = JsonConvert.SerializeObject(request); - var hash = ComputeHash(string.Concat(SettingsService.Instance.ApiBaseUrl, json)); - - if(hash == SettingsService.Instance.LastSyncHash) - { - return new SyncResult - { - Success = true, - Groups = groups, - Users = users - }; - } - - var response = await ApiService.Instance.PostImportAsync(request); - if(response.Succeeded) - { - SettingsService.Instance.LastSyncHash = hash; - - if(SettingsService.Instance.Sync.SyncGroups) - { - SettingsService.Instance.LastGroupSyncDate = now; - } - - if(SettingsService.Instance.Sync.SyncUsers) - { - SettingsService.Instance.LastUserSyncDate = now; - } - - return new SyncResult - { - Success = true, - Groups = groups, - Users = users - }; - } - else - { - RestoreDeltas(startingGroupDelta, startingUserDelta); - return new SyncResult - { - Success = false, - ErrorMessage = response.Errors.FirstOrDefault()?.Message - }; - } - } - catch(Exception e) - { - RestoreDeltas(startingGroupDelta, startingUserDelta); - return new SyncResult - { - Success = false, - ErrorMessage = e.Message - }; - } - } - - private static IDirectoryService GetDirectoryService() - { - switch(SettingsService.Instance.Server.Type) - { - case Enums.DirectoryType.AzureActiveDirectory: - return AzureDirectoryService.Instance; - case Enums.DirectoryType.GSuite: - return GSuiteDirectoryService.Instance; - default: -#if NET461 - return LdapDirectoryService.Instance; -#else - throw new Exception("LdapDirectoryService not supported."); -#endif - } - } - - private static void FlattenUsersToGroups(List currentGroups, List currentGroupsUsers, - List allGroups) - { - foreach(var group in currentGroups) - { - var groupsInThisGroup = allGroups.Where(g => group.GroupMemberReferenceIds.Contains(g.ReferenceId)).ToList(); - var usersInThisGroup = group.UserMemberExternalIds.ToList(); - - if(currentGroupsUsers != null) - { - foreach(var id in currentGroupsUsers) - { - if(!group.UserMemberExternalIds.Contains(id)) - { - group.UserMemberExternalIds.Add(id); - } - } - - usersInThisGroup.AddRange(currentGroupsUsers); - } - - // Recurse it - FlattenUsersToGroups(groupsInThisGroup, usersInThisGroup, allGroups); - } - } - - private static void RestoreDeltas(string groupDelta, string userDelta) - { - if(SettingsService.Instance.Server.Type != Enums.DirectoryType.AzureActiveDirectory) - { - return; - } - - SettingsService.Instance.GroupDeltaToken = groupDelta; - SettingsService.Instance.UserDeltaToken = userDelta; - } - - private static string ComputeHash(string value) - { - if(value == null) - { - return null; - } - - string result = null; - using(var hash = SHA256.Create()) - { - var bytes = Encoding.UTF8.GetBytes(value); - var hashBytes = hash.ComputeHash(bytes); - result = Convert.ToBase64String(hashBytes); - } - - return result; - } - } -} diff --git a/src/Service/Installer.cs b/src/Service/Installer.cs deleted file mode 100644 index 1367208d..00000000 --- a/src/Service/Installer.cs +++ /dev/null @@ -1,78 +0,0 @@ -using System; -using System.ComponentModel; -using System.ServiceProcess; -using System.Configuration.Install; -using System.Diagnostics; -using System.IO; -using System.Security.AccessControl; -using System.Security.Principal; -using Bit.Core.Utilities; - -namespace Service -{ - [RunInstaller(true)] - [DesignerCategory("Code")] - public class Installer : System.Configuration.Install.Installer - { - private IContainer _components = null; - private ServiceProcessInstaller _serviceProcessInstaller; - private ServiceInstaller _serviceInstaller; - - public Installer() - { - Init(); - } - - private void Init() - { - _components = new Container(); - _serviceProcessInstaller = new ServiceProcessInstaller(); - _serviceInstaller = new ServiceInstaller(); - - _serviceProcessInstaller.Account = ServiceAccount.LocalSystem; - _serviceProcessInstaller.AfterInstall += new InstallEventHandler(AfterInstalled); - _serviceProcessInstaller.BeforeInstall += new InstallEventHandler(BeforeInstalled); - - _serviceInstaller.ServiceName = Constants.ProgramName; - _serviceInstaller.Description = "Sync directory groups and users to your Bitwarden organization."; - Installers.AddRange(new System.Configuration.Install.Installer[] { _serviceProcessInstaller, _serviceInstaller }); - } - - private void AfterInstalled(object sender, InstallEventArgs e) - { - var info = new DirectoryInfo(Constants.BaseStoragePath); - if(!info.Exists) - { - info.Create(); - } - - var sec = info.GetAccessControl(); - AddPermission(new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null), sec); - AddPermission(new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null), sec); - AddPermission(new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null), sec); - AddPermission(new SecurityIdentifier(WellKnownSidType.CreatorOwnerSid, null), sec); - AddPermission(WindowsIdentity.GetCurrent().User, sec); - sec.SetAccessRuleProtection(isProtected: true, preserveInheritance: false); - info.SetAccessControl(sec); - } - - private void AddPermission(IdentityReference sid, DirectorySecurity sec) - { - var rule = new FileSystemAccessRule( - sid, - FileSystemRights.FullControl | FileSystemRights.Write | FileSystemRights.Read, - InheritanceFlags.None, - PropagationFlags.NoPropagateInherit, - AccessControlType.Allow); - sec.AddAccessRule(rule); - } - - private void BeforeInstalled(object sender, InstallEventArgs e) - { - if(EventLog.SourceExists(_serviceInstaller.ServiceName)) - { - EventLog.DeleteEventSource(_serviceInstaller.ServiceName); - } - } - } -} diff --git a/src/Service/Program.cs b/src/Service/Program.cs deleted file mode 100644 index 765c56ac..00000000 --- a/src/Service/Program.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.ServiceProcess; -using System.Text; -using System.Threading.Tasks; - -namespace Service -{ - static class Program - { - static void Main() - { - //DebugMode(); - - ServiceBase.Run(new ServiceBase[] - { - new Service() - }); - } - - [Conditional("DEBUG")] - private static void DebugMode() - { - Debugger.Launch(); - } - } -} diff --git a/src/Service/Service.cs b/src/Service/Service.cs deleted file mode 100644 index 77f5d850..00000000 --- a/src/Service/Service.cs +++ /dev/null @@ -1,119 +0,0 @@ -using Bit.Core.Services; -using Bit.Core.Utilities; -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.ServiceProcess; -using System.Text; -using System.Threading; - -namespace Service -{ - [DesignerCategory("Code")] - public class Service : ServiceBase - { - private IContainer _components; - private EventLog _eventLog; - private Timer _timer; - - public Service() - { - ServiceName = Constants.ProgramName; - - _components = new Container(); - - _eventLog = new EventLog(); - _eventLog.Source = ServiceName; - _eventLog.Log = "Application"; - - if(!EventLog.SourceExists(_eventLog.Source)) - { - EventLog.CreateEventSource(_eventLog.Source, _eventLog.Log); - } - } - - protected override void Dispose(bool disposing) - { - if(disposing) - { - _eventLog?.Dispose(); - _eventLog = null; - - _components?.Dispose(); - _components = null; - - _timer?.Dispose(); - _timer = null; - } - - base.Dispose(disposing); - } - - protected override void OnStart(string[] args) - { - _eventLog.WriteEntry("Service started!", EventLogEntryType.Information); - - if(SettingsService.Instance.Server == null) - { - _eventLog.WriteEntry("Server not configured.", EventLogEntryType.Error); - return; - } - - if(SettingsService.Instance.Sync == null) - { - _eventLog.WriteEntry("Sync not configured.", EventLogEntryType.Error); - return; - } - - if(!AuthService.Instance.Authenticated || !AuthService.Instance.OrganizationSet) - { - _eventLog.WriteEntry("Not authenticated with proper organization set.", EventLogEntryType.Error); - return; - } - - var intervalMinutes = SettingsService.Instance.Sync.IntervalMinutes; - if(intervalMinutes < 5) - { - intervalMinutes = 5; - } - - _eventLog.WriteEntry($"Starting timer with {intervalMinutes} minute interval.", EventLogEntryType.Information); - var timerDelegate = new TimerCallback(Callback); - _timer = new Timer(timerDelegate, null, 1000, 60 * 1000 * intervalMinutes); - } - - protected override void OnStop() - { - _eventLog.WriteEntry("Service stopped!", EventLogEntryType.Information); - } - - private void Callback(object stateInfo) - { - try - { - var sw = Stopwatch.StartNew(); - var result = Sync.SyncAllAsync(false, true).GetAwaiter().GetResult(); - sw.Stop(); - if(result.Success) - { - _eventLog.WriteEntry($"Synced {result.Groups?.Count ?? 0} groups, {result.Users?.Count ?? 0} users. " + - $"The sync took {(int)sw.Elapsed.TotalSeconds} seconds to complete.", - EventLogEntryType.SuccessAudit); - } - else - { - _eventLog.WriteEntry($"Sync failed after {(int)sw.Elapsed.TotalSeconds} seconds: {result.ErrorMessage}.", - EventLogEntryType.FailureAudit); - } - } - catch(ApplicationException e) - { - _eventLog.WriteEntry($"Sync exception: {e.Message}", EventLogEntryType.Error); - } - } - } -} diff --git a/src/Service/Service.csproj b/src/Service/Service.csproj deleted file mode 100644 index 073df185..00000000 --- a/src/Service/Service.csproj +++ /dev/null @@ -1,17 +0,0 @@ - - - - Exe - net461 - - - - - - - - - - - - diff --git a/src/Setup/Setup.vdproj b/src/Setup/Setup.vdproj deleted file mode 100644 index cd3849cd..00000000 --- a/src/Setup/Setup.vdproj +++ /dev/null @@ -1,3584 +0,0 @@ -"DeployProject" -{ -"VSVersion" = "3:800" -"ProjectType" = "8:{978C614F-708E-4E1A-B201-565925725DBA}" -"IsWebType" = "8:FALSE" -"ProjectName" = "8:Setup" -"LanguageId" = "3:1033" -"CodePage" = "3:1252" -"UILanguageId" = "3:1033" -"SccProjectName" = "8:" -"SccLocalPath" = "8:" -"SccAuxPath" = "8:" -"SccProvider" = "8:" - "Hierarchy" - { - "Entry" - { - "MsmKey" = "8:_071E1BD00BFC46F0BAA9EA44CE680E4A" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_11F28245CD4A4066A44A74252498FDB4" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_12579073B9F54E7CB34C5AD1267F268E" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_14E1EB7B4C8C4453A456A16854F725F3" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_1BA12AB09DEE452A8AAB38CD4B4AA5A9" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_3289E35012AF46E2AB9F7709394E1211" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_329A70328374CE0CDC0122CBE9418561" - "OwnerKey" = "8:_3289E35012AF46E2AB9F7709394E1211" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_329A70328374CE0CDC0122CBE9418561" - "OwnerKey" = "8:_E62B773B59D04E7CAFE2D6DB6C826444" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_329A70328374CE0CDC0122CBE9418561" - "OwnerKey" = "8:_DA2F1AE5C4E14A9FAF61F3E26E3B43EE" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_329A70328374CE0CDC0122CBE9418561" - "OwnerKey" = "8:_88D5D3EC0B30445AB0C0CA47DCC69EC4" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_329A70328374CE0CDC0122CBE9418561" - "OwnerKey" = "8:_C2875819AE97C327543D1A514656DA68" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_37ED9D7E665F45CFAA036BE45BA55584" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_3D9CAF370BFD4029BCC1DC8792C77A7A" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_401538F0D7E847B4AA81F256913311CB" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_4875FB3864CD408C99F7AE6D4CFD0AFD" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_4BAF1445CDB464484115A5267F8A8470" - "OwnerKey" = "8:_3289E35012AF46E2AB9F7709394E1211" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_4BAF1445CDB464484115A5267F8A8470" - "OwnerKey" = "8:_E62B773B59D04E7CAFE2D6DB6C826444" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_4BAF1445CDB464484115A5267F8A8470" - "OwnerKey" = "8:_AF8E613DE9AD474D9696A34995874B44" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_4BAF1445CDB464484115A5267F8A8470" - "OwnerKey" = "8:_546EBFAB70CB4942A12744DE206FEBB3" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_4BAF1445CDB464484115A5267F8A8470" - "OwnerKey" = "8:_C2875819AE97C327543D1A514656DA68" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_4D5A5DB70BA04B84B6F6436C2935B589" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_4F101A164D944C2BB911D6902498BD53" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_508AC04F48F94FEB9A3EFCD889BBDC29" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_52F87A2613FE4E54A8A41ECC17DB2B6A" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_546EBFAB70CB4942A12744DE206FEBB3" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_549EFBE4205C4815B7787608ADD57389" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_54F5C28535CE481A827E4C3D396B9D2D" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_635A488199624E938166B4CB6CEC2F1C" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_73853B765D95425DB86A02A63F2C7BD2" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_7ED80B2151394586EEC47CCBDF6A4F45" - "OwnerKey" = "8:_071E1BD00BFC46F0BAA9EA44CE680E4A" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_7ED80B2151394586EEC47CCBDF6A4F45" - "OwnerKey" = "8:_F74536C4A1BF4B6285CA00A111DE8DC6" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_7ED80B2151394586EEC47CCBDF6A4F45" - "OwnerKey" = "8:_E62B773B59D04E7CAFE2D6DB6C826444" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_7ED80B2151394586EEC47CCBDF6A4F45" - "OwnerKey" = "8:_E5B25D31FCC3440094480B715D28E51E" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_7ED80B2151394586EEC47CCBDF6A4F45" - "OwnerKey" = "8:_CEEBDAA360B9431FBE353E86FD8F0830" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_7ED80B2151394586EEC47CCBDF6A4F45" - "OwnerKey" = "8:_C7AD5D7845CE480CBE78014A637F94E1" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_7ED80B2151394586EEC47CCBDF6A4F45" - "OwnerKey" = "8:_C0A039246A0F4997801DA40B740C6DEA" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_7ED80B2151394586EEC47CCBDF6A4F45" - "OwnerKey" = "8:_95F3CE695F3B4766A32D4CEEB94A0485" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_7ED80B2151394586EEC47CCBDF6A4F45" - "OwnerKey" = "8:_73853B765D95425DB86A02A63F2C7BD2" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_7ED80B2151394586EEC47CCBDF6A4F45" - "OwnerKey" = "8:_549EFBE4205C4815B7787608ADD57389" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_7ED80B2151394586EEC47CCBDF6A4F45" - "OwnerKey" = "8:_C2875819AE97C327543D1A514656DA68" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_7ED80B2151394586EEC47CCBDF6A4F45" - "OwnerKey" = "8:_4875FB3864CD408C99F7AE6D4CFD0AFD" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_7ED80B2151394586EEC47CCBDF6A4F45" - "OwnerKey" = "8:_37ED9D7E665F45CFAA036BE45BA55584" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_7ED80B2151394586EEC47CCBDF6A4F45" - "OwnerKey" = "8:_3289E35012AF46E2AB9F7709394E1211" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_7ED80B2151394586EEC47CCBDF6A4F45" - "OwnerKey" = "8:_329A70328374CE0CDC0122CBE9418561" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_7ED80B2151394586EEC47CCBDF6A4F45" - "OwnerKey" = "8:_BDDF68895F38EDDF8E2704B6C6DA0DC1" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_7ED80B2151394586EEC47CCBDF6A4F45" - "OwnerKey" = "8:_AB11C1DEF767EEA6CB3DADC6BCCFDE5C" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_7ED80B2151394586EEC47CCBDF6A4F45" - "OwnerKey" = "8:_4BAF1445CDB464484115A5267F8A8470" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_7ED80B2151394586EEC47CCBDF6A4F45" - "OwnerKey" = "8:_8613360C7EE24F960B8D2B275F3D1B28" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_7ED80B2151394586EEC47CCBDF6A4F45" - "OwnerKey" = "8:_12579073B9F54E7CB34C5AD1267F268E" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_7ED80B2151394586EEC47CCBDF6A4F45" - "OwnerKey" = "8:_A6FC5C600AB7F187578CC29DFAC3262E" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_802D9DA6BBBA481F988DE2B46024CBB8" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_82B2F98C018149938BAE256922EB3D9B" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_82DAE97C028C45B6A0482D28D796453F" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_85BC720CBA194C2281A99DC9A56F8FDA" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_8613360C7EE24F960B8D2B275F3D1B28" - "OwnerKey" = "8:_FE31CDDF5FC2E1B2EECF6C67B29B3C43" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_8613360C7EE24F960B8D2B275F3D1B28" - "OwnerKey" = "8:_F74536C4A1BF4B6285CA00A111DE8DC6" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_8613360C7EE24F960B8D2B275F3D1B28" - "OwnerKey" = "8:_E62B773B59D04E7CAFE2D6DB6C826444" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_8613360C7EE24F960B8D2B275F3D1B28" - "OwnerKey" = "8:_CEEBDAA360B9431FBE353E86FD8F0830" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_8613360C7EE24F960B8D2B275F3D1B28" - "OwnerKey" = "8:_90BE2E4A4D814902998C932518C76E9C" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_8613360C7EE24F960B8D2B275F3D1B28" - "OwnerKey" = "8:_54F5C28535CE481A827E4C3D396B9D2D" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_8613360C7EE24F960B8D2B275F3D1B28" - "OwnerKey" = "8:_C2875819AE97C327543D1A514656DA68" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_8613360C7EE24F960B8D2B275F3D1B28" - "OwnerKey" = "8:_508AC04F48F94FEB9A3EFCD889BBDC29" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_8613360C7EE24F960B8D2B275F3D1B28" - "OwnerKey" = "8:_3D9CAF370BFD4029BCC1DC8792C77A7A" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_8613360C7EE24F960B8D2B275F3D1B28" - "OwnerKey" = "8:_3289E35012AF46E2AB9F7709394E1211" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_8613360C7EE24F960B8D2B275F3D1B28" - "OwnerKey" = "8:_4BAF1445CDB464484115A5267F8A8470" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_8767CA05411747C88D751CB9756D29E3" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_88D5D3EC0B30445AB0C0CA47DCC69EC4" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_89981CCDA2054138A68D552C31B6E5CC" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_90BE2E4A4D814902998C932518C76E9C" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_90C3EF72C6AE4F4FA1E8DFB3DC84FB14" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_924ACD96E56E422D871A2B5117BF63E7" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_95F3CE695F3B4766A32D4CEEB94A0485" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_A6FC5C600AB7F187578CC29DFAC3262E" - "OwnerKey" = "8:_12579073B9F54E7CB34C5AD1267F268E" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_A6FC5C600AB7F187578CC29DFAC3262E" - "OwnerKey" = "8:_F74536C4A1BF4B6285CA00A111DE8DC6" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_A6FC5C600AB7F187578CC29DFAC3262E" - "OwnerKey" = "8:_E62B773B59D04E7CAFE2D6DB6C826444" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_A6FC5C600AB7F187578CC29DFAC3262E" - "OwnerKey" = "8:_CEEBDAA360B9431FBE353E86FD8F0830" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_A6FC5C600AB7F187578CC29DFAC3262E" - "OwnerKey" = "8:_95F3CE695F3B4766A32D4CEEB94A0485" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_A6FC5C600AB7F187578CC29DFAC3262E" - "OwnerKey" = "8:_C2875819AE97C327543D1A514656DA68" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_A6FC5C600AB7F187578CC29DFAC3262E" - "OwnerKey" = "8:_508AC04F48F94FEB9A3EFCD889BBDC29" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_A6FC5C600AB7F187578CC29DFAC3262E" - "OwnerKey" = "8:_3D9CAF370BFD4029BCC1DC8792C77A7A" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_A6FC5C600AB7F187578CC29DFAC3262E" - "OwnerKey" = "8:_3289E35012AF46E2AB9F7709394E1211" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_A6FC5C600AB7F187578CC29DFAC3262E" - "OwnerKey" = "8:_4BAF1445CDB464484115A5267F8A8470" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_A6FC5C600AB7F187578CC29DFAC3262E" - "OwnerKey" = "8:_8613360C7EE24F960B8D2B275F3D1B28" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_A6FC5C600AB7F187578CC29DFAC3262E" - "OwnerKey" = "8:_FE31CDDF5FC2E1B2EECF6C67B29B3C43" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_AB11C1DEF767EEA6CB3DADC6BCCFDE5C" - "OwnerKey" = "8:_3289E35012AF46E2AB9F7709394E1211" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_AB11C1DEF767EEA6CB3DADC6BCCFDE5C" - "OwnerKey" = "8:_E62B773B59D04E7CAFE2D6DB6C826444" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_AB11C1DEF767EEA6CB3DADC6BCCFDE5C" - "OwnerKey" = "8:_C0A039246A0F4997801DA40B740C6DEA" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_AB11C1DEF767EEA6CB3DADC6BCCFDE5C" - "OwnerKey" = "8:_73853B765D95425DB86A02A63F2C7BD2" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_AB11C1DEF767EEA6CB3DADC6BCCFDE5C" - "OwnerKey" = "8:_C2875819AE97C327543D1A514656DA68" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_AB11C1DEF767EEA6CB3DADC6BCCFDE5C" - "OwnerKey" = "8:_BDDF68895F38EDDF8E2704B6C6DA0DC1" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_AF00D6D1BD694BC3B2B4B4BF554C6B5E" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_AF8E613DE9AD474D9696A34995874B44" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_B0EBE6188F4E417CA5836F87D4F1E0EA" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_BDDF68895F38EDDF8E2704B6C6DA0DC1" - "OwnerKey" = "8:_3289E35012AF46E2AB9F7709394E1211" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_BDDF68895F38EDDF8E2704B6C6DA0DC1" - "OwnerKey" = "8:_E62B773B59D04E7CAFE2D6DB6C826444" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_BDDF68895F38EDDF8E2704B6C6DA0DC1" - "OwnerKey" = "8:_C2875819AE97C327543D1A514656DA68" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_C0A039246A0F4997801DA40B740C6DEA" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_C2875819AE97C327543D1A514656DA68" - "OwnerKey" = "8:_52F87A2613FE4E54A8A41ECC17DB2B6A" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_C2875819AE97C327543D1A514656DA68" - "OwnerKey" = "8:_D8C95911CD8B4187B846DF57921DA439" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_C5C87096FADE4F09B53D1924AC9C2A22" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_C79B1C7A5FFAF4E7D9D88655D2CAF953" - "OwnerKey" = "8:_071E1BD00BFC46F0BAA9EA44CE680E4A" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_C79B1C7A5FFAF4E7D9D88655D2CAF953" - "OwnerKey" = "8:_F74536C4A1BF4B6285CA00A111DE8DC6" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_C79B1C7A5FFAF4E7D9D88655D2CAF953" - "OwnerKey" = "8:_E62B773B59D04E7CAFE2D6DB6C826444" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_C79B1C7A5FFAF4E7D9D88655D2CAF953" - "OwnerKey" = "8:_CEEBDAA360B9431FBE353E86FD8F0830" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_C79B1C7A5FFAF4E7D9D88655D2CAF953" - "OwnerKey" = "8:_C7AD5D7845CE480CBE78014A637F94E1" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_C79B1C7A5FFAF4E7D9D88655D2CAF953" - "OwnerKey" = "8:_C0A039246A0F4997801DA40B740C6DEA" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_C79B1C7A5FFAF4E7D9D88655D2CAF953" - "OwnerKey" = "8:_95F3CE695F3B4766A32D4CEEB94A0485" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_C79B1C7A5FFAF4E7D9D88655D2CAF953" - "OwnerKey" = "8:_73853B765D95425DB86A02A63F2C7BD2" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_C79B1C7A5FFAF4E7D9D88655D2CAF953" - "OwnerKey" = "8:_549EFBE4205C4815B7787608ADD57389" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_C79B1C7A5FFAF4E7D9D88655D2CAF953" - "OwnerKey" = "8:_C2875819AE97C327543D1A514656DA68" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_C79B1C7A5FFAF4E7D9D88655D2CAF953" - "OwnerKey" = "8:_508AC04F48F94FEB9A3EFCD889BBDC29" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_C79B1C7A5FFAF4E7D9D88655D2CAF953" - "OwnerKey" = "8:_4875FB3864CD408C99F7AE6D4CFD0AFD" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_C79B1C7A5FFAF4E7D9D88655D2CAF953" - "OwnerKey" = "8:_3D9CAF370BFD4029BCC1DC8792C77A7A" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_C79B1C7A5FFAF4E7D9D88655D2CAF953" - "OwnerKey" = "8:_3289E35012AF46E2AB9F7709394E1211" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_C79B1C7A5FFAF4E7D9D88655D2CAF953" - "OwnerKey" = "8:_BDDF68895F38EDDF8E2704B6C6DA0DC1" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_C79B1C7A5FFAF4E7D9D88655D2CAF953" - "OwnerKey" = "8:_AB11C1DEF767EEA6CB3DADC6BCCFDE5C" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_C79B1C7A5FFAF4E7D9D88655D2CAF953" - "OwnerKey" = "8:_4BAF1445CDB464484115A5267F8A8470" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_C79B1C7A5FFAF4E7D9D88655D2CAF953" - "OwnerKey" = "8:_FE31CDDF5FC2E1B2EECF6C67B29B3C43" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_C79B1C7A5FFAF4E7D9D88655D2CAF953" - "OwnerKey" = "8:_8613360C7EE24F960B8D2B275F3D1B28" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_C79B1C7A5FFAF4E7D9D88655D2CAF953" - "OwnerKey" = "8:_12579073B9F54E7CB34C5AD1267F268E" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_C79B1C7A5FFAF4E7D9D88655D2CAF953" - "OwnerKey" = "8:_A6FC5C600AB7F187578CC29DFAC3262E" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_C7AD5D7845CE480CBE78014A637F94E1" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_CB79659D89A5B7A2F5AA330ACDB284D3" - "OwnerKey" = "8:_3289E35012AF46E2AB9F7709394E1211" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_CB79659D89A5B7A2F5AA330ACDB284D3" - "OwnerKey" = "8:_E62B773B59D04E7CAFE2D6DB6C826444" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_CB79659D89A5B7A2F5AA330ACDB284D3" - "OwnerKey" = "8:_C2875819AE97C327543D1A514656DA68" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_CD98A3EF573543ECB55B3C4FDDC7C14A" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_CEEBDAA360B9431FBE353E86FD8F0830" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_D8C95911CD8B4187B846DF57921DA439" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_DA2F1AE5C4E14A9FAF61F3E26E3B43EE" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_DD76ABE7544744B59EC7728B748039F5" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_E5698510332B451BA5C5B64C229E8EEA" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_E5B25D31FCC3440094480B715D28E51E" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_E62B773B59D04E7CAFE2D6DB6C826444" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_EE23D1420138433B8831924CB5B1F57B" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_F74536C4A1BF4B6285CA00A111DE8DC6" - "OwnerKey" = "8:_UNDEFINED" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_FE31CDDF5FC2E1B2EECF6C67B29B3C43" - "OwnerKey" = "8:_3289E35012AF46E2AB9F7709394E1211" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_FE31CDDF5FC2E1B2EECF6C67B29B3C43" - "OwnerKey" = "8:_E62B773B59D04E7CAFE2D6DB6C826444" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_FE31CDDF5FC2E1B2EECF6C67B29B3C43" - "OwnerKey" = "8:_C2875819AE97C327543D1A514656DA68" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_C79B1C7A5FFAF4E7D9D88655D2CAF953" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_F74536C4A1BF4B6285CA00A111DE8DC6" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_E62B773B59D04E7CAFE2D6DB6C826444" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_E5B25D31FCC3440094480B715D28E51E" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_DD76ABE7544744B59EC7728B748039F5" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_DA2F1AE5C4E14A9FAF61F3E26E3B43EE" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_D8C95911CD8B4187B846DF57921DA439" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_CEEBDAA360B9431FBE353E86FD8F0830" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_CD98A3EF573543ECB55B3C4FDDC7C14A" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_C7AD5D7845CE480CBE78014A637F94E1" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_C0A039246A0F4997801DA40B740C6DEA" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_B0EBE6188F4E417CA5836F87D4F1E0EA" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_AF8E613DE9AD474D9696A34995874B44" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_AF00D6D1BD694BC3B2B4B4BF554C6B5E" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_95F3CE695F3B4766A32D4CEEB94A0485" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_924ACD96E56E422D871A2B5117BF63E7" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_90C3EF72C6AE4F4FA1E8DFB3DC84FB14" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_90BE2E4A4D814902998C932518C76E9C" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_88D5D3EC0B30445AB0C0CA47DCC69EC4" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_8767CA05411747C88D751CB9756D29E3" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_82DAE97C028C45B6A0482D28D796453F" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_802D9DA6BBBA481F988DE2B46024CBB8" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_73853B765D95425DB86A02A63F2C7BD2" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_635A488199624E938166B4CB6CEC2F1C" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_54F5C28535CE481A827E4C3D396B9D2D" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_549EFBE4205C4815B7787608ADD57389" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_546EBFAB70CB4942A12744DE206FEBB3" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_52F87A2613FE4E54A8A41ECC17DB2B6A" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_C2875819AE97C327543D1A514656DA68" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_508AC04F48F94FEB9A3EFCD889BBDC29" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_4875FB3864CD408C99F7AE6D4CFD0AFD" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_401538F0D7E847B4AA81F256913311CB" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_3D9CAF370BFD4029BCC1DC8792C77A7A" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_37ED9D7E665F45CFAA036BE45BA55584" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_3289E35012AF46E2AB9F7709394E1211" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_329A70328374CE0CDC0122CBE9418561" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_BDDF68895F38EDDF8E2704B6C6DA0DC1" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_AB11C1DEF767EEA6CB3DADC6BCCFDE5C" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_4BAF1445CDB464484115A5267F8A8470" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_FE31CDDF5FC2E1B2EECF6C67B29B3C43" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_8613360C7EE24F960B8D2B275F3D1B28" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_CB79659D89A5B7A2F5AA330ACDB284D3" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_1BA12AB09DEE452A8AAB38CD4B4AA5A9" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_14E1EB7B4C8C4453A456A16854F725F3" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_12579073B9F54E7CB34C5AD1267F268E" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_A6FC5C600AB7F187578CC29DFAC3262E" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_11F28245CD4A4066A44A74252498FDB4" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_071E1BD00BFC46F0BAA9EA44CE680E4A" - "MsmSig" = "8:_UNDEFINED" - } - "Entry" - { - "MsmKey" = "8:_UNDEFINED" - "OwnerKey" = "8:_7ED80B2151394586EEC47CCBDF6A4F45" - "MsmSig" = "8:_UNDEFINED" - } - } - "Configurations" - { - "Debug" - { - "DisplayName" = "8:Debug" - "IsDebugOnly" = "11:TRUE" - "IsReleaseOnly" = "11:FALSE" - "OutputFilename" = "8:Debug\\Setup.msi" - "PackageFilesAs" = "3:2" - "PackageFileSize" = "3:-2147483648" - "CabType" = "3:1" - "Compression" = "3:2" - "SignOutput" = "11:FALSE" - "CertificateFile" = "8:" - "PrivateKeyFile" = "8:" - "TimeStampServer" = "8:" - "InstallerBootstrapper" = "3:2" - "BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}" - { - "Enabled" = "11:TRUE" - "PromptEnabled" = "11:TRUE" - "PrerequisitesLocation" = "2:1" - "Url" = "8:" - "ComponentsUrl" = "8:" - "Items" - { - "{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:.NETFramework,Version=v4.6.1" - { - "Name" = "8:Microsoft .NET Framework 4.6.1 (x86 and x64)" - "ProductCode" = "8:.NETFramework,Version=v4.6.1" - } - } - } - } - "Release" - { - "DisplayName" = "8:Release" - "IsDebugOnly" = "11:FALSE" - "IsReleaseOnly" = "11:TRUE" - "OutputFilename" = "8:Release\\Setup.msi" - "PackageFilesAs" = "3:2" - "PackageFileSize" = "3:-2147483648" - "CabType" = "3:1" - "Compression" = "3:2" - "SignOutput" = "11:FALSE" - "CertificateFile" = "8:" - "PrivateKeyFile" = "8:" - "TimeStampServer" = "8:" - "InstallerBootstrapper" = "3:2" - "BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}" - { - "Enabled" = "11:TRUE" - "PromptEnabled" = "11:TRUE" - "PrerequisitesLocation" = "2:1" - "Url" = "8:" - "ComponentsUrl" = "8:" - "Items" - { - "{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:.NETFramework,Version=v4.6.1" - { - "Name" = "8:Microsoft .NET Framework 4.6.1 (x86 and x64)" - "ProductCode" = "8:.NETFramework,Version=v4.6.1" - } - } - } - } - } - "Deployable" - { - "CustomAction" - { - "{4AA51A2D-7D85-4A59-BA75-B0809FC8B380}:_280A547DB03040E383A5051DDBEE46D1" - { - "Name" = "8:Service.exe" - "Condition" = "8:" - "Object" = "8:_52F87A2613FE4E54A8A41ECC17DB2B6A" - "FileType" = "3:2" - "InstallAction" = "3:2" - "Arguments" = "8:" - "EntryPoint" = "8:" - "Sequence" = "3:1" - "Identifier" = "8:_6065668D_DCDA_430D_BE7D_E69DDF4FFA60" - "InstallerClass" = "11:TRUE" - "CustomActionData" = "8:" - } - "{4AA51A2D-7D85-4A59-BA75-B0809FC8B380}:_4A932191D0CD4A2BA36B61178F9D05C7" - { - "Name" = "8:Service.exe" - "Condition" = "8:" - "Object" = "8:_52F87A2613FE4E54A8A41ECC17DB2B6A" - "FileType" = "3:2" - "InstallAction" = "3:3" - "Arguments" = "8:" - "EntryPoint" = "8:" - "Sequence" = "3:1" - "Identifier" = "8:_1752A5B8_B161_46B9_A38D_45A574443604" - "InstallerClass" = "11:TRUE" - "CustomActionData" = "8:" - } - "{4AA51A2D-7D85-4A59-BA75-B0809FC8B380}:_AD92921B11E541F1A9C014295863C8BB" - { - "Name" = "8:Service.exe" - "Condition" = "8:" - "Object" = "8:_52F87A2613FE4E54A8A41ECC17DB2B6A" - "FileType" = "3:2" - "InstallAction" = "3:4" - "Arguments" = "8:" - "EntryPoint" = "8:" - "Sequence" = "3:1" - "Identifier" = "8:_E1372336_239B_4208_AFBB_A3C1B4F4AB9E" - "InstallerClass" = "11:TRUE" - "CustomActionData" = "8:" - } - "{4AA51A2D-7D85-4A59-BA75-B0809FC8B380}:_C2B28BED0A354E76BA6B2B71D12FA0AF" - { - "Name" = "8:Service.exe" - "Condition" = "8:" - "Object" = "8:_52F87A2613FE4E54A8A41ECC17DB2B6A" - "FileType" = "3:2" - "InstallAction" = "3:1" - "Arguments" = "8:" - "EntryPoint" = "8:" - "Sequence" = "3:1" - "Identifier" = "8:_3B55B4DD_27BB_45D1_A735_2081EFFAF13A" - "InstallerClass" = "11:TRUE" - "CustomActionData" = "8:" - } - } - "DefaultFeature" - { - "Name" = "8:DefaultFeature" - "Title" = "8:" - "Description" = "8:" - } - "ExternalPersistence" - { - "LaunchCondition" - { - "{A06ECF26-33A3-4562-8140-9B0E340D4F24}:_A3E0FA44D4BC4B169922C23E20F478FC" - { - "Name" = "8:.NET Framework" - "Message" = "8:[VSDNETMSG]" - "FrameworkVersion" = "8:.NETFramework,Version=v4.6.1" - "AllowLaterVersions" = "11:FALSE" - "InstallUrl" = "8:http://go.microsoft.com/fwlink/?LinkId=671728" - } - } - } - "File" - { - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_071E1BD00BFC46F0BAA9EA44CE680E4A" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:Google.Apis.Core, Version=1.31.0.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_071E1BD00BFC46F0BAA9EA44CE680E4A" - { - "Name" = "8:Google.Apis.Core.dll" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:..\\Service\\bin\\Release\\net461\\Google.Apis.Core.dll" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_11F28245CD4A4066A44A74252498FDB4" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:System.Security.Cryptography.Algorithms, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_11F28245CD4A4066A44A74252498FDB4" - { - "Name" = "8:System.Security.Cryptography.Algorithms.dll" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:..\\Console\\bin\\Release\\net461\\System.Security.Cryptography.Algorithms.dll" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_12579073B9F54E7CB34C5AD1267F268E" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:Google.Apis, Version=1.31.0.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_12579073B9F54E7CB34C5AD1267F268E" - { - "Name" = "8:Google.Apis.dll" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:..\\Service\\bin\\Release\\net461\\Google.Apis.dll" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_14E1EB7B4C8C4453A456A16854F725F3" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:System.Net.Http, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_14E1EB7B4C8C4453A456A16854F725F3" - { - "Name" = "8:System.Net.Http.dll" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:..\\Console\\bin\\Release\\net461\\System.Net.Http.dll" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_1BA12AB09DEE452A8AAB38CD4B4AA5A9" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:System.Security.Cryptography.Primitives, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_1BA12AB09DEE452A8AAB38CD4B4AA5A9" - { - "Name" = "8:System.Security.Cryptography.Primitives.dll" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:..\\Service\\bin\\Release\\net461\\System.Security.Cryptography.Primitives.dll" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_3289E35012AF46E2AB9F7709394E1211" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:Core, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_3289E35012AF46E2AB9F7709394E1211" - { - "Name" = "8:Core.dll" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:..\\Service\\bin\\Release\\net461\\Core.dll" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_329A70328374CE0CDC0122CBE9418561" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:Microsoft.IdentityModel.Clients.ActiveDirectory, Version=3.17.2.31801, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_329A70328374CE0CDC0122CBE9418561" - { - "Name" = "8:Microsoft.IdentityModel.Clients.ActiveDirectory.DLL" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:Microsoft.IdentityModel.Clients.ActiveDirectory.DLL" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:TRUE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_37ED9D7E665F45CFAA036BE45BA55584" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:Microsoft.IdentityModel.Clients.ActiveDirectory, Version=3.17.2.31801, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_37ED9D7E665F45CFAA036BE45BA55584" - { - "Name" = "8:Microsoft.IdentityModel.Clients.ActiveDirectory.dll" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:..\\Console\\bin\\Release\\net461\\Microsoft.IdentityModel.Clients.ActiveDirectory.dll" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_3D9CAF370BFD4029BCC1DC8792C77A7A" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:Google.Apis.Admin.Directory.directory_v1, Version=1.31.0.1061, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_3D9CAF370BFD4029BCC1DC8792C77A7A" - { - "Name" = "8:Google.Apis.Admin.Directory.directory_v1.dll" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:..\\Service\\bin\\Release\\net461\\Google.Apis.Admin.Directory.directory_v1.dll" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_401538F0D7E847B4AA81F256913311CB" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:System.Security.Cryptography.Algorithms, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_401538F0D7E847B4AA81F256913311CB" - { - "Name" = "8:System.Security.Cryptography.Algorithms.dll" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:..\\Service\\bin\\Release\\net461\\System.Security.Cryptography.Algorithms.dll" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_4875FB3864CD408C99F7AE6D4CFD0AFD" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:Microsoft.Graph.Core, Version=1.6.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_4875FB3864CD408C99F7AE6D4CFD0AFD" - { - "Name" = "8:Microsoft.Graph.Core.dll" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:..\\Service\\bin\\Release\\net461\\Microsoft.Graph.Core.dll" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_4BAF1445CDB464484115A5267F8A8470" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:Google.Apis.Auth, Version=1.31.0.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_4BAF1445CDB464484115A5267F8A8470" - { - "Name" = "8:Google.Apis.Auth.DLL" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:Google.Apis.Auth.DLL" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:TRUE" - "IsolateTo" = "8:" - } - "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_4D5A5DB70BA04B84B6F6436C2935B589" - { - "SourcePath" = "8:..\\Console\\bin\\Release\\net461\\Console.exe.config" - "TargetName" = "8:Console.exe.config" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_4F101A164D944C2BB911D6902498BD53" - { - "SourcePath" = "8:icon.ico" - "TargetName" = "8:icon.ico" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_508AC04F48F94FEB9A3EFCD889BBDC29" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:Google.Apis.Admin.Directory.directory_v1, Version=1.31.0.1061, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_508AC04F48F94FEB9A3EFCD889BBDC29" - { - "Name" = "8:Google.Apis.Admin.Directory.directory_v1.dll" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:..\\Console\\bin\\Release\\net461\\Google.Apis.Admin.Directory.directory_v1.dll" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_52F87A2613FE4E54A8A41ECC17DB2B6A" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:Service, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_52F87A2613FE4E54A8A41ECC17DB2B6A" - { - "Name" = "8:Service.exe" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:..\\Service\\bin\\Release\\net461\\Service.exe" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_546EBFAB70CB4942A12744DE206FEBB3" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:Google.Apis.Auth.PlatformServices, Version=1.31.0.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_546EBFAB70CB4942A12744DE206FEBB3" - { - "Name" = "8:Google.Apis.Auth.PlatformServices.dll" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:..\\Service\\bin\\Release\\net461\\Google.Apis.Auth.PlatformServices.dll" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_549EFBE4205C4815B7787608ADD57389" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:Microsoft.Graph.Core, Version=1.6.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_549EFBE4205C4815B7787608ADD57389" - { - "Name" = "8:Microsoft.Graph.Core.dll" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:..\\Console\\bin\\Release\\net461\\Microsoft.Graph.Core.dll" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_54F5C28535CE481A827E4C3D396B9D2D" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:Google.Apis.PlatformServices, Version=1.31.0.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_54F5C28535CE481A827E4C3D396B9D2D" - { - "Name" = "8:Google.Apis.PlatformServices.dll" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:..\\Console\\bin\\Release\\net461\\Google.Apis.PlatformServices.dll" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_635A488199624E938166B4CB6CEC2F1C" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:BouncyCastle.Crypto, Version=1.8.1.0, Culture=neutral, PublicKeyToken=0e99375e54769942, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_635A488199624E938166B4CB6CEC2F1C" - { - "Name" = "8:BouncyCastle.Crypto.dll" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:..\\Console\\bin\\Release\\net461\\BouncyCastle.Crypto.dll" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_73853B765D95425DB86A02A63F2C7BD2" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:Microsoft.Graph, Version=1.6.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_73853B765D95425DB86A02A63F2C7BD2" - { - "Name" = "8:Microsoft.Graph.dll" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:..\\Console\\bin\\Release\\net461\\Microsoft.Graph.dll" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_7ED80B2151394586EEC47CCBDF6A4F45" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:System.Net.Http, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_7ED80B2151394586EEC47CCBDF6A4F45" - { - "Name" = "8:System.Net.Http.DLL" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:System.Net.Http.DLL" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:TRUE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_802D9DA6BBBA481F988DE2B46024CBB8" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:BouncyCastle.Crypto, Version=1.8.1.0, Culture=neutral, PublicKeyToken=0e99375e54769942, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_802D9DA6BBBA481F988DE2B46024CBB8" - { - "Name" = "8:BouncyCastle.Crypto.dll" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:..\\Service\\bin\\Release\\net461\\BouncyCastle.Crypto.dll" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_82B2F98C018149938BAE256922EB3D9B" - { - "SourcePath" = "8:..\\Console\\bin\\Release\\net461\\Console.pdb" - "TargetName" = "8:Console.pdb" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_82DAE97C028C45B6A0482D28D796453F" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:System.Net.Http, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_82DAE97C028C45B6A0482D28D796453F" - { - "Name" = "8:System.Net.Http.dll" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:..\\Service\\bin\\Release\\net461\\System.Net.Http.dll" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_85BC720CBA194C2281A99DC9A56F8FDA" - { - "SourcePath" = "8:..\\Service\\bin\\Release\\net461\\Service.exe.config" - "TargetName" = "8:Service.exe.config" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_8613360C7EE24F960B8D2B275F3D1B28" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:Google.Apis, Version=1.31.0.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_8613360C7EE24F960B8D2B275F3D1B28" - { - "Name" = "8:Google.Apis.DLL" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:Google.Apis.DLL" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:TRUE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_8767CA05411747C88D751CB9756D29E3" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_8767CA05411747C88D751CB9756D29E3" - { - "Name" = "8:Newtonsoft.Json.dll" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:..\\Service\\bin\\Release\\net461\\Newtonsoft.Json.dll" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_88D5D3EC0B30445AB0C0CA47DCC69EC4" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:Microsoft.IdentityModel.Clients.ActiveDirectory.Platform, Version=3.17.2.31801, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_88D5D3EC0B30445AB0C0CA47DCC69EC4" - { - "Name" = "8:Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:..\\Console\\bin\\Release\\net461\\Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_89981CCDA2054138A68D552C31B6E5CC" - { - "SourcePath" = "8:setup-banner.bmp" - "TargetName" = "8:setup-banner.bmp" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_90BE2E4A4D814902998C932518C76E9C" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:Google.Apis.PlatformServices, Version=1.31.0.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_90BE2E4A4D814902998C932518C76E9C" - { - "Name" = "8:Google.Apis.PlatformServices.dll" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:..\\Service\\bin\\Release\\net461\\Google.Apis.PlatformServices.dll" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_90C3EF72C6AE4F4FA1E8DFB3DC84FB14" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:System.Security.Cryptography.Encoding, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_90C3EF72C6AE4F4FA1E8DFB3DC84FB14" - { - "Name" = "8:System.Security.Cryptography.Encoding.dll" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:..\\Service\\bin\\Release\\net461\\System.Security.Cryptography.Encoding.dll" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_924ACD96E56E422D871A2B5117BF63E7" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:System.Security.Cryptography.Encoding, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_924ACD96E56E422D871A2B5117BF63E7" - { - "Name" = "8:System.Security.Cryptography.Encoding.dll" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:..\\Console\\bin\\Release\\net461\\System.Security.Cryptography.Encoding.dll" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_95F3CE695F3B4766A32D4CEEB94A0485" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:Google.Apis, Version=1.31.0.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_95F3CE695F3B4766A32D4CEEB94A0485" - { - "Name" = "8:Google.Apis.dll" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:..\\Console\\bin\\Release\\net461\\Google.Apis.dll" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_A6FC5C600AB7F187578CC29DFAC3262E" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:Google.Apis.Core, Version=1.31.0.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_A6FC5C600AB7F187578CC29DFAC3262E" - { - "Name" = "8:Google.Apis.Core.DLL" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:Google.Apis.Core.DLL" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:TRUE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_AB11C1DEF767EEA6CB3DADC6BCCFDE5C" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:Microsoft.Graph.Core, Version=1.6.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_AB11C1DEF767EEA6CB3DADC6BCCFDE5C" - { - "Name" = "8:Microsoft.Graph.Core.DLL" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:Microsoft.Graph.Core.DLL" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:TRUE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_AF00D6D1BD694BC3B2B4B4BF554C6B5E" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:System.Security.Cryptography.X509Certificates, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_AF00D6D1BD694BC3B2B4B4BF554C6B5E" - { - "Name" = "8:System.Security.Cryptography.X509Certificates.dll" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:..\\Service\\bin\\Release\\net461\\System.Security.Cryptography.X509Certificates.dll" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_AF8E613DE9AD474D9696A34995874B44" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:Google.Apis.Auth.PlatformServices, Version=1.31.0.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_AF8E613DE9AD474D9696A34995874B44" - { - "Name" = "8:Google.Apis.Auth.PlatformServices.dll" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:..\\Console\\bin\\Release\\net461\\Google.Apis.Auth.PlatformServices.dll" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_B0EBE6188F4E417CA5836F87D4F1E0EA" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:System.Security.Cryptography.X509Certificates, Version=4.1.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_B0EBE6188F4E417CA5836F87D4F1E0EA" - { - "Name" = "8:System.Security.Cryptography.X509Certificates.dll" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:..\\Console\\bin\\Release\\net461\\System.Security.Cryptography.X509Certificates.dll" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_BDDF68895F38EDDF8E2704B6C6DA0DC1" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:Microsoft.Graph, Version=1.6.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_BDDF68895F38EDDF8E2704B6C6DA0DC1" - { - "Name" = "8:Microsoft.Graph.DLL" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:Microsoft.Graph.DLL" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:TRUE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_C0A039246A0F4997801DA40B740C6DEA" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:Microsoft.Graph, Version=1.6.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_C0A039246A0F4997801DA40B740C6DEA" - { - "Name" = "8:Microsoft.Graph.dll" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:..\\Service\\bin\\Release\\net461\\Microsoft.Graph.dll" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_C2875819AE97C327543D1A514656DA68" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:Core, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_C2875819AE97C327543D1A514656DA68" - { - "Name" = "8:Core.DLL" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:Core.DLL" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:TRUE" - "IsolateTo" = "8:" - } - "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_C5C87096FADE4F09B53D1924AC9C2A22" - { - "SourcePath" = "8:..\\Service\\bin\\Release\\net461\\Core.pdb" - "TargetName" = "8:Core.pdb" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_C79B1C7A5FFAF4E7D9D88655D2CAF953" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_C79B1C7A5FFAF4E7D9D88655D2CAF953" - { - "Name" = "8:Newtonsoft.Json.DLL" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:Newtonsoft.Json.DLL" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:TRUE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_C7AD5D7845CE480CBE78014A637F94E1" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:Google.Apis.Core, Version=1.31.0.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_C7AD5D7845CE480CBE78014A637F94E1" - { - "Name" = "8:Google.Apis.Core.dll" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:..\\Console\\bin\\Release\\net461\\Google.Apis.Core.dll" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_CB79659D89A5B7A2F5AA330ACDB284D3" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:BouncyCastle.Crypto, Version=1.8.1.0, Culture=neutral, PublicKeyToken=0e99375e54769942, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_CB79659D89A5B7A2F5AA330ACDB284D3" - { - "Name" = "8:BouncyCastle.Crypto.DLL" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:BouncyCastle.Crypto.DLL" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:TRUE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_CD98A3EF573543ECB55B3C4FDDC7C14A" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:System.Security.Cryptography.Primitives, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_CD98A3EF573543ECB55B3C4FDDC7C14A" - { - "Name" = "8:System.Security.Cryptography.Primitives.dll" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:..\\Console\\bin\\Release\\net461\\System.Security.Cryptography.Primitives.dll" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_CEEBDAA360B9431FBE353E86FD8F0830" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:Google.Apis.Auth, Version=1.31.0.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_CEEBDAA360B9431FBE353E86FD8F0830" - { - "Name" = "8:Google.Apis.Auth.dll" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:..\\Console\\bin\\Release\\net461\\Google.Apis.Auth.dll" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_D8C95911CD8B4187B846DF57921DA439" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:Console, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_D8C95911CD8B4187B846DF57921DA439" - { - "Name" = "8:Console.exe" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:..\\Console\\bin\\Release\\net461\\Console.exe" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_DA2F1AE5C4E14A9FAF61F3E26E3B43EE" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:Microsoft.IdentityModel.Clients.ActiveDirectory.Platform, Version=3.17.2.31801, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_DA2F1AE5C4E14A9FAF61F3E26E3B43EE" - { - "Name" = "8:Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:..\\Service\\bin\\Release\\net461\\Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_DD76ABE7544744B59EC7728B748039F5" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_DD76ABE7544744B59EC7728B748039F5" - { - "Name" = "8:Newtonsoft.Json.dll" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:..\\Console\\bin\\Release\\net461\\Newtonsoft.Json.dll" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_E5698510332B451BA5C5B64C229E8EEA" - { - "SourcePath" = "8:..\\Service\\bin\\Release\\net461\\Service.pdb" - "TargetName" = "8:Service.pdb" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_E5B25D31FCC3440094480B715D28E51E" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:Microsoft.IdentityModel.Clients.ActiveDirectory, Version=3.17.2.31801, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_E5B25D31FCC3440094480B715D28E51E" - { - "Name" = "8:Microsoft.IdentityModel.Clients.ActiveDirectory.dll" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:..\\Service\\bin\\Release\\net461\\Microsoft.IdentityModel.Clients.ActiveDirectory.dll" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_E62B773B59D04E7CAFE2D6DB6C826444" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:Core, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_E62B773B59D04E7CAFE2D6DB6C826444" - { - "Name" = "8:Core.dll" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:..\\Console\\bin\\Release\\net461\\Core.dll" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_EE23D1420138433B8831924CB5B1F57B" - { - "SourcePath" = "8:..\\Console\\bin\\Release\\net461\\Core.pdb" - "TargetName" = "8:Core.pdb" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_F74536C4A1BF4B6285CA00A111DE8DC6" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:Google.Apis.Auth, Version=1.31.0.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_F74536C4A1BF4B6285CA00A111DE8DC6" - { - "Name" = "8:Google.Apis.Auth.dll" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:..\\Service\\bin\\Release\\net461\\Google.Apis.Auth.dll" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:FALSE" - "IsolateTo" = "8:" - } - "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_FE31CDDF5FC2E1B2EECF6C67B29B3C43" - { - "AssemblyRegister" = "3:1" - "AssemblyIsInGAC" = "11:FALSE" - "AssemblyAsmDisplayName" = "8:Google.Apis.Admin.Directory.directory_v1, Version=1.31.0.1061, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL" - "ScatterAssemblies" - { - "_FE31CDDF5FC2E1B2EECF6C67B29B3C43" - { - "Name" = "8:Google.Apis.Admin.Directory.directory_v1.DLL" - "Attributes" = "3:512" - } - } - "SourcePath" = "8:Google.Apis.Admin.Directory.directory_v1.DLL" - "TargetName" = "8:" - "Tag" = "8:" - "Folder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Vital" = "11:TRUE" - "ReadOnly" = "11:FALSE" - "Hidden" = "11:FALSE" - "System" = "11:FALSE" - "Permanent" = "11:FALSE" - "SharedLegacy" = "11:FALSE" - "PackageAs" = "3:1" - "Register" = "3:1" - "Exclude" = "11:FALSE" - "IsDependency" = "11:TRUE" - "IsolateTo" = "8:" - } - } - "FileType" - { - } - "Folder" - { - "{3C67513D-01DD-4637-8A68-80971EB9504F}:_195A3C659FB74030BD0F825A0E4FE2A6" - { - "DefaultLocation" = "8:[ProgramFilesFolder][Manufacturer]\\[ProductName]" - "Name" = "8:#1925" - "AlwaysCreate" = "11:FALSE" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Property" = "8:TARGETDIR" - "Folders" - { - } - } - "{1525181F-901A-416C-8A58-119130FE478E}:_B24ED42A924347F38ACEA2B8936547AB" - { - "Name" = "8:#1919" - "AlwaysCreate" = "11:FALSE" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Property" = "8:ProgramMenuFolder" - "Folders" - { - } - } - "{1525181F-901A-416C-8A58-119130FE478E}:_D1A0DD0F78B24586B983FCFB7841D659" - { - "Name" = "8:#1916" - "AlwaysCreate" = "11:FALSE" - "Condition" = "8:" - "Transitive" = "11:FALSE" - "Property" = "8:DesktopFolder" - "Folders" - { - } - } - } - "LaunchCondition" - { - } - "Locator" - { - } - "MsiBootstrapper" - { - "LangId" = "3:1033" - "RequiresElevation" = "11:FALSE" - } - "Product" - { - "Name" = "8:Microsoft Visual Studio" - "ProductName" = "8:Bitwarden Directory Connector" - "ProductCode" = "8:{1E27A7B6-8CA5-4C8E-8DC8-A354AFF221FC}" - "PackageCode" = "8:{2C7F1A22-288B-4572-9A03-5DFEF0E63962}" - "UpgradeCode" = "8:{AD840539-416A-4C0F-9549-8D9EE828F80B}" - "AspNetVersion" = "8:4.0.30319.0" - "RestartWWWService" = "11:FALSE" - "RemovePreviousVersions" = "11:TRUE" - "DetectNewerInstalledVersion" = "11:TRUE" - "InstallAllUsers" = "11:FALSE" - "ProductVersion" = "8:1.0.0" - "Manufacturer" = "8:Bitwarden" - "ARPHELPTELEPHONE" = "8:" - "ARPHELPLINK" = "8:https://bitwarden.com/contact" - "Title" = "8:Bitwarden Directory Connector" - "Subject" = "8:" - "ARPCONTACT" = "8:8bit Solutions LLC" - "Keywords" = "8:Bitwarden" - "ARPCOMMENTS" = "8:Bitwarden organizations directory connector." - "ARPURLINFOABOUT" = "8:https://bitwarden.com" - "ARPPRODUCTICON" = "8:_4F101A164D944C2BB911D6902498BD53" - "ARPIconIndex" = "3:0" - "SearchPath" = "8:" - "UseSystemSearchPath" = "11:TRUE" - "TargetPlatform" = "3:0" - "PreBuildEvent" = "8:" - "PostBuildEvent" = "8:" - "RunPostBuildEvent" = "3:0" - } - "Registry" - { - "HKLM" - { - "Keys" - { - "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_21194B7CD2ED44D580C7558E5B79FDFF" - { - "Name" = "8:Software" - "Condition" = "8:" - "AlwaysCreate" = "11:FALSE" - "DeleteAtUninstall" = "11:FALSE" - "Transitive" = "11:FALSE" - "Keys" - { - "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_C9FC7C1E634F49049CC6FA82686FE436" - { - "Name" = "8:[Manufacturer]" - "Condition" = "8:" - "AlwaysCreate" = "11:FALSE" - "DeleteAtUninstall" = "11:FALSE" - "Transitive" = "11:FALSE" - "Keys" - { - } - "Values" - { - } - } - } - "Values" - { - } - } - } - } - "HKCU" - { - "Keys" - { - "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_091044DE11D54D6E9BFDF6DEE96CC3C7" - { - "Name" = "8:Software" - "Condition" = "8:" - "AlwaysCreate" = "11:FALSE" - "DeleteAtUninstall" = "11:FALSE" - "Transitive" = "11:FALSE" - "Keys" - { - "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_8ED629BB7ED84660942BD41A11F67F1A" - { - "Name" = "8:[Manufacturer]" - "Condition" = "8:" - "AlwaysCreate" = "11:FALSE" - "DeleteAtUninstall" = "11:FALSE" - "Transitive" = "11:FALSE" - "Keys" - { - } - "Values" - { - } - } - } - "Values" - { - } - } - } - } - "HKCR" - { - "Keys" - { - } - } - "HKU" - { - "Keys" - { - } - } - "HKPU" - { - "Keys" - { - } - } - } - "Sequences" - { - } - "Shortcut" - { - "{970C0BB2-C7D0-45D7-ABFA-7EC378858BC0}:_8C86030DE24241BD9AE9E140F8D3B239" - { - "Name" = "8:Directory Connector Console" - "Arguments" = "8:" - "Description" = "8:" - "ShowCmd" = "3:1" - "IconIndex" = "3:0" - "Transitive" = "11:FALSE" - "Target" = "8:_D8C95911CD8B4187B846DF57921DA439" - "Folder" = "8:_D1A0DD0F78B24586B983FCFB7841D659" - "WorkingFolder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Icon" = "8:_4F101A164D944C2BB911D6902498BD53" - "Feature" = "8:" - } - "{970C0BB2-C7D0-45D7-ABFA-7EC378858BC0}:_B1B52AF8665E4BE0818B3425F09A6B25" - { - "Name" = "8:Directory Connector Console" - "Arguments" = "8:" - "Description" = "8:" - "ShowCmd" = "3:1" - "IconIndex" = "3:0" - "Transitive" = "11:FALSE" - "Target" = "8:_D8C95911CD8B4187B846DF57921DA439" - "Folder" = "8:_B24ED42A924347F38ACEA2B8936547AB" - "WorkingFolder" = "8:_195A3C659FB74030BD0F825A0E4FE2A6" - "Icon" = "8:_4F101A164D944C2BB911D6902498BD53" - "Feature" = "8:" - } - } - "UserInterface" - { - "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_1A25166B5E8D4B80B732E3170390DF6D" - { - "Name" = "8:#1900" - "Sequence" = "3:1" - "Attributes" = "3:1" - "Dialogs" - { - "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_978B2FF75C3D4D8D8D2772AA316432CD" - { - "Sequence" = "3:200" - "DisplayName" = "8:Installation Folder" - "UseDynamicProperties" = "11:TRUE" - "IsDependency" = "11:FALSE" - "SourcePath" = "8:\\VsdFolderDlg.wid" - "Properties" - { - "BannerBitmap" - { - "Name" = "8:BannerBitmap" - "DisplayName" = "8:#1001" - "Description" = "8:#1101" - "Type" = "3:8" - "ContextData" = "8:Bitmap" - "Attributes" = "3:4" - "Setting" = "3:2" - "Value" = "8:_89981CCDA2054138A68D552C31B6E5CC" - "UsePlugInResources" = "11:TRUE" - } - "InstallAllUsersVisible" - { - "Name" = "8:InstallAllUsersVisible" - "DisplayName" = "8:#1059" - "Description" = "8:#1159" - "Type" = "3:5" - "ContextData" = "8:1;True=1;False=0" - "Attributes" = "3:0" - "Setting" = "3:0" - "Value" = "3:1" - "DefaultValue" = "3:1" - "UsePlugInResources" = "11:TRUE" - } - } - } - "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_9A80D790C01C461ABC94975FB93DFFA9" - { - "Sequence" = "3:100" - "DisplayName" = "8:Welcome" - "UseDynamicProperties" = "11:TRUE" - "IsDependency" = "11:FALSE" - "SourcePath" = "8:\\VsdWelcomeDlg.wid" - "Properties" - { - "BannerBitmap" - { - "Name" = "8:BannerBitmap" - "DisplayName" = "8:#1001" - "Description" = "8:#1101" - "Type" = "3:8" - "ContextData" = "8:Bitmap" - "Attributes" = "3:4" - "Setting" = "3:2" - "Value" = "8:_89981CCDA2054138A68D552C31B6E5CC" - "UsePlugInResources" = "11:TRUE" - } - "CopyrightWarning" - { - "Name" = "8:CopyrightWarning" - "DisplayName" = "8:#1002" - "Description" = "8:#1102" - "Type" = "3:3" - "ContextData" = "8:" - "Attributes" = "3:0" - "Setting" = "3:1" - "Value" = "8:#1202" - "DefaultValue" = "8:#1202" - "UsePlugInResources" = "11:TRUE" - } - "Welcome" - { - "Name" = "8:Welcome" - "DisplayName" = "8:#1003" - "Description" = "8:#1103" - "Type" = "3:3" - "ContextData" = "8:" - "Attributes" = "3:0" - "Setting" = "3:1" - "Value" = "8:#1203" - "DefaultValue" = "8:#1203" - "UsePlugInResources" = "11:TRUE" - } - } - } - "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_D65E636F1ED24C26BFF6B598655662DE" - { - "Sequence" = "3:300" - "DisplayName" = "8:Confirm Installation" - "UseDynamicProperties" = "11:TRUE" - "IsDependency" = "11:FALSE" - "SourcePath" = "8:\\VsdConfirmDlg.wid" - "Properties" - { - "BannerBitmap" - { - "Name" = "8:BannerBitmap" - "DisplayName" = "8:#1001" - "Description" = "8:#1101" - "Type" = "3:8" - "ContextData" = "8:Bitmap" - "Attributes" = "3:4" - "Setting" = "3:2" - "Value" = "8:_89981CCDA2054138A68D552C31B6E5CC" - "UsePlugInResources" = "11:TRUE" - } - } - } - } - } - "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_30AF428D37CD43A4AF9E1454C564CA60" - { - "Name" = "8:#1902" - "Sequence" = "3:2" - "Attributes" = "3:3" - "Dialogs" - { - "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_E82DE45F2799414F9D6A83D155ED5A22" - { - "Sequence" = "3:100" - "DisplayName" = "8:Finished" - "UseDynamicProperties" = "11:TRUE" - "IsDependency" = "11:FALSE" - "SourcePath" = "8:\\VsdAdminFinishedDlg.wid" - "Properties" - { - "BannerBitmap" - { - "Name" = "8:BannerBitmap" - "DisplayName" = "8:#1001" - "Description" = "8:#1101" - "Type" = "3:8" - "ContextData" = "8:Bitmap" - "Attributes" = "3:4" - "Setting" = "3:2" - "Value" = "8:_89981CCDA2054138A68D552C31B6E5CC" - "UsePlugInResources" = "11:TRUE" - } - } - } - } - } - "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_314812C974B447BE857E5EE7BC698CE1" - { - "Name" = "8:#1901" - "Sequence" = "3:1" - "Attributes" = "3:2" - "Dialogs" - { - "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_9347258AB06A445E8FDDCB6E604993B8" - { - "Sequence" = "3:100" - "DisplayName" = "8:Progress" - "UseDynamicProperties" = "11:TRUE" - "IsDependency" = "11:FALSE" - "SourcePath" = "8:\\VsdProgressDlg.wid" - "Properties" - { - "BannerBitmap" - { - "Name" = "8:BannerBitmap" - "DisplayName" = "8:#1001" - "Description" = "8:#1101" - "Type" = "3:8" - "ContextData" = "8:Bitmap" - "Attributes" = "3:4" - "Setting" = "3:2" - "Value" = "8:_89981CCDA2054138A68D552C31B6E5CC" - "UsePlugInResources" = "11:TRUE" - } - "ShowProgress" - { - "Name" = "8:ShowProgress" - "DisplayName" = "8:#1009" - "Description" = "8:#1109" - "Type" = "3:5" - "ContextData" = "8:1;True=1;False=0" - "Attributes" = "3:0" - "Setting" = "3:0" - "Value" = "3:1" - "DefaultValue" = "3:1" - "UsePlugInResources" = "11:TRUE" - } - } - } - } - } - "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_3336E97E18D346BA8FF536D7979C2251" - { - "Name" = "8:#1900" - "Sequence" = "3:2" - "Attributes" = "3:1" - "Dialogs" - { - "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_17E72DC1D07A4A038772D4578057CA69" - { - "Sequence" = "3:100" - "DisplayName" = "8:Welcome" - "UseDynamicProperties" = "11:TRUE" - "IsDependency" = "11:FALSE" - "SourcePath" = "8:\\VsdAdminWelcomeDlg.wid" - "Properties" - { - "BannerBitmap" - { - "Name" = "8:BannerBitmap" - "DisplayName" = "8:#1001" - "Description" = "8:#1101" - "Type" = "3:8" - "ContextData" = "8:Bitmap" - "Attributes" = "3:4" - "Setting" = "3:2" - "Value" = "8:_89981CCDA2054138A68D552C31B6E5CC" - "UsePlugInResources" = "11:TRUE" - } - "CopyrightWarning" - { - "Name" = "8:CopyrightWarning" - "DisplayName" = "8:#1002" - "Description" = "8:#1102" - "Type" = "3:3" - "ContextData" = "8:" - "Attributes" = "3:0" - "Setting" = "3:1" - "Value" = "8:#1202" - "DefaultValue" = "8:#1202" - "UsePlugInResources" = "11:TRUE" - } - "Welcome" - { - "Name" = "8:Welcome" - "DisplayName" = "8:#1003" - "Description" = "8:#1103" - "Type" = "3:3" - "ContextData" = "8:" - "Attributes" = "3:0" - "Setting" = "3:1" - "Value" = "8:#1203" - "DefaultValue" = "8:#1203" - "UsePlugInResources" = "11:TRUE" - } - } - } - "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_49B914FE3602424D801FC619E70E87F2" - { - "Sequence" = "3:300" - "DisplayName" = "8:Confirm Installation" - "UseDynamicProperties" = "11:TRUE" - "IsDependency" = "11:FALSE" - "SourcePath" = "8:\\VsdAdminConfirmDlg.wid" - "Properties" - { - "BannerBitmap" - { - "Name" = "8:BannerBitmap" - "DisplayName" = "8:#1001" - "Description" = "8:#1101" - "Type" = "3:8" - "ContextData" = "8:Bitmap" - "Attributes" = "3:4" - "Setting" = "3:2" - "Value" = "8:_89981CCDA2054138A68D552C31B6E5CC" - "UsePlugInResources" = "11:TRUE" - } - } - } - "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_70D5E93D354E4CEBBA5BA440E857BD96" - { - "Sequence" = "3:200" - "DisplayName" = "8:Installation Folder" - "UseDynamicProperties" = "11:TRUE" - "IsDependency" = "11:FALSE" - "SourcePath" = "8:\\VsdAdminFolderDlg.wid" - "Properties" - { - "BannerBitmap" - { - "Name" = "8:BannerBitmap" - "DisplayName" = "8:#1001" - "Description" = "8:#1101" - "Type" = "3:8" - "ContextData" = "8:Bitmap" - "Attributes" = "3:4" - "Setting" = "3:2" - "Value" = "8:_89981CCDA2054138A68D552C31B6E5CC" - "UsePlugInResources" = "11:TRUE" - } - } - } - } - } - "{2479F3F5-0309-486D-8047-8187E2CE5BA0}:_8A07E66A812C4E50B389FBB6666721DF" - { - "UseDynamicProperties" = "11:FALSE" - "IsDependency" = "11:FALSE" - "SourcePath" = "8:\\VsdUserInterface.wim" - } - "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_90820F15743C481BB98AB7340B8CED70" - { - "Name" = "8:#1902" - "Sequence" = "3:1" - "Attributes" = "3:3" - "Dialogs" - { - "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_AE4316411B2442D985DE96A5253A9C52" - { - "Sequence" = "3:100" - "DisplayName" = "8:Finished" - "UseDynamicProperties" = "11:TRUE" - "IsDependency" = "11:FALSE" - "SourcePath" = "8:\\VsdFinishedDlg.wid" - "Properties" - { - "BannerBitmap" - { - "Name" = "8:BannerBitmap" - "DisplayName" = "8:#1001" - "Description" = "8:#1101" - "Type" = "3:8" - "ContextData" = "8:Bitmap" - "Attributes" = "3:4" - "Setting" = "3:2" - "Value" = "8:_89981CCDA2054138A68D552C31B6E5CC" - "UsePlugInResources" = "11:TRUE" - } - "UpdateText" - { - "Name" = "8:UpdateText" - "DisplayName" = "8:#1058" - "Description" = "8:#1158" - "Type" = "3:15" - "ContextData" = "8:" - "Attributes" = "3:0" - "Setting" = "3:1" - "Value" = "8:#1258" - "DefaultValue" = "8:#1258" - "UsePlugInResources" = "11:TRUE" - } - } - } - } - } - "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_9B54D238640D497785ED590D8049334D" - { - "Name" = "8:#1901" - "Sequence" = "3:2" - "Attributes" = "3:2" - "Dialogs" - { - "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_C81D153ECBAF499E9BA89FABF1ABEE4A" - { - "Sequence" = "3:100" - "DisplayName" = "8:Progress" - "UseDynamicProperties" = "11:TRUE" - "IsDependency" = "11:FALSE" - "SourcePath" = "8:\\VsdAdminProgressDlg.wid" - "Properties" - { - "BannerBitmap" - { - "Name" = "8:BannerBitmap" - "DisplayName" = "8:#1001" - "Description" = "8:#1101" - "Type" = "3:8" - "ContextData" = "8:Bitmap" - "Attributes" = "3:4" - "Setting" = "3:2" - "Value" = "8:_89981CCDA2054138A68D552C31B6E5CC" - "UsePlugInResources" = "11:TRUE" - } - "ShowProgress" - { - "Name" = "8:ShowProgress" - "DisplayName" = "8:#1009" - "Description" = "8:#1109" - "Type" = "3:5" - "ContextData" = "8:1;True=1;False=0" - "Attributes" = "3:0" - "Setting" = "3:0" - "Value" = "3:1" - "DefaultValue" = "3:1" - "UsePlugInResources" = "11:TRUE" - } - } - } - } - } - "{2479F3F5-0309-486D-8047-8187E2CE5BA0}:_E1583C143078467BA05C53C355B6350C" - { - "UseDynamicProperties" = "11:FALSE" - "IsDependency" = "11:FALSE" - "SourcePath" = "8:\\VsdBasicDialogs.wim" - } - } - "MergeModule" - { - } - "ProjectOutput" - { - } - } -} diff --git a/src/Setup/icon.ico b/src/Setup/icon.ico deleted file mode 100644 index 5f7ca9bd..00000000 Binary files a/src/Setup/icon.ico and /dev/null differ diff --git a/src/Setup/setup-banner.bmp b/src/Setup/setup-banner.bmp deleted file mode 100644 index 4d4afe32..00000000 Binary files a/src/Setup/setup-banner.bmp and /dev/null differ diff --git a/src/global.d.ts b/src/global.d.ts new file mode 100644 index 00000000..4859a086 --- /dev/null +++ b/src/global.d.ts @@ -0,0 +1,2 @@ +declare function escape(s: string): string; +declare function unescape(s: string): string; diff --git a/src/index.html b/src/index.html new file mode 100644 index 00000000..ab5f5d55 --- /dev/null +++ b/src/index.html @@ -0,0 +1,14 @@ + + + + + + Bitwarden + + + + +
+
+ + diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 00000000..995cdc54 --- /dev/null +++ b/src/main.ts @@ -0,0 +1,66 @@ +import { app, BrowserWindow } from 'electron'; +import * as path from 'path'; + +// import { ElectronMainMessagingService } from 'jslib/electron/services/desktopMainMessaging.service'; +import { I18nService } from 'jslib/services/i18n.service'; + +import { MessagingMain } from './main/messaging.main'; + +import { ElectronLogService } from 'jslib/electron/services/electronLog.service'; +import { ElectronStorageService } from 'jslib/electron/services/electronStorage.service'; +import { WindowMain } from 'jslib/electron/window.main'; + +export class Main { + logService: ElectronLogService; + i18nService: I18nService; + storageService: ElectronStorageService; + + windowMain: WindowMain; + messagingMain: MessagingMain; + + constructor() { + // Set paths for portable builds + let appDataPath = null; + if (process.env.BITWARDEN_APPDATA_DIR != null) { + appDataPath = process.env.BITWARDEN_APPDATA_DIR; + } else if (process.platform === 'win32' && process.env.PORTABLE_EXECUTABLE_DIR != null) { + appDataPath = path.join(process.env.PORTABLE_EXECUTABLE_DIR, 'bitwarden-appdata'); + } else if (process.platform === 'linux' && process.env.SNAP_USER_DATA != null) { + appDataPath = path.join(process.env.SNAP_USER_DATA, 'appdata'); + } + + if (appDataPath != null) { + app.setPath('userData', appDataPath); + } + app.setPath('logs', path.join(app.getPath('userData'), 'logs')); + + const args = process.argv.slice(1); + const watch = args.some((val) => val === '--watch'); + + if (watch) { + // tslint:disable-next-line + require('electron-reload')(__dirname, {}); + } + + this.logService = new ElectronLogService(null, app.getPath('userData')); + // this.i18nService = new I18nService('en', './locales/'); + this.storageService = new ElectronStorageService(); + // this.messagingService = new DesktopMainMessagingService(this); + + this.windowMain = new WindowMain(this.storageService); + this.messagingMain = new MessagingMain(this); + } + + bootstrap() { + this.windowMain.init().then(async () => { + await this.i18nService.init(app.getLocale()); + this.messagingMain.init(); + }, (e: any) => { + // tslint:disable-next-line + console.error(e); + }); + } +} + +const main = new Main(); +main.bootstrap(); diff --git a/src/main/messaging.main.ts b/src/main/messaging.main.ts new file mode 100644 index 00000000..942fede1 --- /dev/null +++ b/src/main/messaging.main.ts @@ -0,0 +1,74 @@ +import { + app, + ipcMain, +} from 'electron'; + +import { + deletePassword, + getPassword, + setPassword, +} from 'keytar'; + +import { Main } from '../main'; + +const KeytarService = 'Bitwarden'; +const SyncInterval = 5 * 60 * 1000; // 5 minutes + +export class MessagingMain { + private syncTimeout: NodeJS.Timer; + + constructor(private main: Main) { } + + init() { + this.scheduleNextSync(); + ipcMain.on('messagingService', async (event: any, message: any) => this.onMessage(message)); + + ipcMain.on('keytar', async (event: any, message: any) => { + try { + let val: string = null; + if (message.action && message.key) { + if (message.action === 'getPassword') { + val = await getPassword(KeytarService, message.key); + } else if (message.action === 'setPassword' && message.value) { + await setPassword(KeytarService, message.key, message.value); + } else if (message.action === 'deletePassword') { + await deletePassword(KeytarService, message.key); + } + } + + event.returnValue = val; + } catch { + event.returnValue = null; + } + }); + } + + onMessage(message: any) { + switch (message.command) { + case 'scheduleNextSync': + this.scheduleNextSync(); + break; + case 'updateAppMenu': + // this.main.menuMain.updateApplicationMenuState(message.isAuthenticated, message.isLocked); + break; + default: + break; + } + } + + private scheduleNextSync() { + if (this.syncTimeout) { + global.clearTimeout(this.syncTimeout); + } + + this.syncTimeout = global.setTimeout(() => { + if (this.main.windowMain.win == null) { + return; + } + + this.main.windowMain.win.webContents.send('messagingService', { + command: 'checkSyncVault', + }); + }, SyncInterval); + } +} diff --git a/src/package-lock.json b/src/package-lock.json new file mode 100644 index 00000000..47753f08 --- /dev/null +++ b/src/package-lock.json @@ -0,0 +1,303 @@ +{ + "name": "bitwarden", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "1.0.3" + } + }, + "bluebird": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", + "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" + }, + "bluebird-lst": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/bluebird-lst/-/bluebird-lst-1.0.5.tgz", + "integrity": "sha512-Ey0bDNys5qpYPhZ/oQ9vOEvD0TYQDTILMXWP2iGfvMg7rSDde+oV4aQQgqRH+CvBFNz2BSDQnPGMUl6LKBUUQA==", + "requires": { + "bluebird": "3.5.1" + } + }, + "builder-util-runtime": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-4.2.0.tgz", + "integrity": "sha512-cROCExnJOJvRD58HHcnrrgyRAoDHGZT0hKox0op7vTuuuRC/1JKMXvSR+Hxy7KWy/aEmKu0HfSqMd4znDEqQsA==", + "requires": { + "bluebird-lst": "1.0.5", + "debug": "3.1.0", + "fs-extra-p": "4.5.2", + "sax": "1.2.4" + } + }, + "conf": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/conf/-/conf-1.4.0.tgz", + "integrity": "sha512-bzlVWS2THbMetHqXKB8ypsXN4DQ/1qopGwNJi1eYbpwesJcd86FBjFciCQX/YwAhp9bM7NVnPFqZ5LpV7gP0Dg==", + "requires": { + "dot-prop": "4.2.0", + "env-paths": "1.0.0", + "make-dir": "1.2.0", + "pkg-up": "2.0.0", + "write-file-atomic": "2.3.0" + } + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "dot-prop": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", + "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", + "requires": { + "is-obj": "1.0.1" + } + }, + "electron-is-dev": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/electron-is-dev/-/electron-is-dev-0.3.0.tgz", + "integrity": "sha1-FOb9pcaOnk7L7/nM8DfL18BcWv4=" + }, + "electron-log": { + "version": "2.2.14", + "resolved": "https://registry.npmjs.org/electron-log/-/electron-log-2.2.14.tgz", + "integrity": "sha512-Rj+XyK4nShe/nv9v1Uks4KEfjtQ6N+eSnx5CLpAjG6rlyUdAflyFHoybcHSLoq9l9pGavclULWS5IXgk8umc2g==" + }, + "electron-store": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/electron-store/-/electron-store-1.3.0.tgz", + "integrity": "sha512-r1Pdl5MwpiCxgbsl0qnwv/GABO5+J/JTO16+KyqL+bOITIk9o3cq3Sw69uO9NgPkpfcKeEwxtJFbtbiBlGTiDA==", + "requires": { + "conf": "1.4.0" + } + }, + "electron-updater": { + "version": "2.21.4", + "resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-2.21.4.tgz", + "integrity": "sha512-x6QSbyxgGR3szIOBtFoCJH0TfgB55AWHaXmilNgorfvpnCdEMQEATxEzLOW0JCzzcB5y3vBrawvmMUEdXwutmA==", + "requires": { + "bluebird-lst": "1.0.5", + "builder-util-runtime": "4.2.0", + "electron-is-dev": "0.3.0", + "fs-extra-p": "4.5.2", + "js-yaml": "3.11.0", + "lazy-val": "1.0.3", + "lodash.isequal": "4.5.0", + "semver": "5.5.0", + "source-map-support": "0.5.4" + } + }, + "env-paths": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-1.0.0.tgz", + "integrity": "sha1-QWgTO0K7BcOKNbGuQ5fIKYqzaeA=" + }, + "esprima": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", + "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==" + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "requires": { + "locate-path": "2.0.0" + } + }, + "fs-extra": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz", + "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==", + "requires": { + "graceful-fs": "4.1.11", + "jsonfile": "4.0.0", + "universalify": "0.1.1" + } + }, + "fs-extra-p": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/fs-extra-p/-/fs-extra-p-4.5.2.tgz", + "integrity": "sha512-ZYqFpBdy9w7PsK+vB30j+TnHOyWHm/CJbUq1qqoE8tb71m6qgk5Wa7gp3MYQdlGFxb9vfznF+yD4jcl8l+y91A==", + "requires": { + "bluebird-lst": "1.0.5", + "fs-extra": "5.0.0" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=" + }, + "js-yaml": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.11.0.tgz", + "integrity": "sha512-saJstZWv7oNeOyBh3+Dx1qWzhW0+e6/8eDzo7p5rDFqxntSztloLtuKu+Ejhtq82jsilwOIZYsCz+lIjthg1Hw==", + "requires": { + "argparse": "1.0.10", + "esprima": "4.0.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "4.1.11" + } + }, + "keytar": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/keytar/-/keytar-4.1.0.tgz", + "integrity": "sha512-L3KqiSMtpVitlug4uuI+K5XLne9SAVEFWE8SCQIhQiH0IA/CTbon5v5prVLKK0Ken54o2O8V9HceKagpwJum+Q==", + "requires": { + "nan": "2.5.1" + } + }, + "lazy-val": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.3.tgz", + "integrity": "sha512-pjCf3BYk+uv3ZcPzEVM0BFvO9Uw58TmlrU0oG5tTrr9Kcid3+kdKxapH8CjdYmVa2nO5wOoZn2rdvZx2PKj/xg==" + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "requires": { + "p-locate": "2.0.0", + "path-exists": "3.0.0" + } + }, + "lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" + }, + "make-dir": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.2.0.tgz", + "integrity": "sha512-aNUAa4UMg/UougV25bbrU4ZaaKNjJ/3/xnvg/twpmKROPdKZPZ9wGgI0opdZzO8q/zUFawoUuixuOv33eZ61Iw==", + "requires": { + "pify": "3.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "nan": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.5.1.tgz", + "integrity": "sha1-1bAWkSUzJql6K77p5hxV2NYDUeI=" + }, + "p-limit": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz", + "integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==", + "requires": { + "p-try": "1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "requires": { + "p-limit": "1.2.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + }, + "pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", + "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", + "requires": { + "find-up": "2.1.0" + } + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==" + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "source-map-support": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.4.tgz", + "integrity": "sha512-PETSPG6BjY1AHs2t64vS2aqAgu6dMIMXJULWFBGbh2Gr8nVLbCFDo6i/RMMvviIQ2h1Z8+5gQhVKSn2je9nmdg==", + "requires": { + "source-map": "0.6.1" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "universalify": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz", + "integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc=" + }, + "write-file-atomic": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz", + "integrity": "sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA==", + "requires": { + "graceful-fs": "4.1.11", + "imurmurhash": "0.1.4", + "signal-exit": "3.0.2" + } + } + } +} diff --git a/src/package.json b/src/package.json new file mode 100644 index 00000000..689edb51 --- /dev/null +++ b/src/package.json @@ -0,0 +1,20 @@ +{ + "name": "bitwarden", + "productName": "Bitwarden Directory Connector", + "description": "A secure and free password manager for all of your devices.", + "version": "1.0.0", + "author": "8bit Solutions LLC (https://bitwarden.com)", + "homepage": "https://bitwarden.com", + "license": "GPL-3.0", + "main": "main.js", + "repository": { + "type": "git", + "url": "https://github.com/bitwarden/desktop" + }, + "dependencies": { + "electron-log": "2.2.14", + "electron-store": "1.3.0", + "electron-updater": "2.21.4", + "keytar": "4.1.0" + } +} diff --git a/src/scss/base.scss b/src/scss/base.scss new file mode 100644 index 00000000..c6512be2 --- /dev/null +++ b/src/scss/base.scss @@ -0,0 +1,75 @@ +@import "variables.scss"; + +* { + box-sizing: border-box; + padding: 0; + margin: 0; +} + +html, body { + height: 100%; + background-color: $background-color-alt2; + font-family: $font-family-sans-serif; + font-size: $font-size-base; + color: $text-color; + line-height: $line-height-base; +} + +h1, h2, h3, h4, h5, h6 { + font-family: $font-family-sans-serif; + color: $text-color; +} + +p { + margin-bottom: 10px; +} + +ul, ol { + margin-bottom: 10px; +} + +img { + border: none; +} + +a { + color: $brand-primary; + text-decoration: none; + + &:hover, &:focus { + color: darken($brand-primary, 6%); + } +} + +input, select, textarea, button { + font-size: $font-size-base; + font-family: $font-family-sans-serif; +} + +button { + white-space: nowrap; + cursor: pointer; +} + +textarea { + resize: vertical; +} + +div:not(.modal)::-webkit-scrollbar { + width: 10px; + height: 10px; +} + +div:not(.modal)::-webkit-scrollbar-track { + background-color: transparent; +} + +div:not(.modal)::-webkit-scrollbar-thumb { + background-color: rgba(100,100,100,.2); + border-radius: 10px; + margin-right: 1px; + + &:hover { + background-color: rgba(100,100,100,.4); + } +} diff --git a/src/scss/box.scss b/src/scss/box.scss new file mode 100644 index 00000000..0e04ad77 --- /dev/null +++ b/src/scss/box.scss @@ -0,0 +1,260 @@ +@import "variables.scss"; + +.box { + width: 100%; + + .box-header { + margin: 0 10px 5px 10px; + color: $gray-light; + text-transform: uppercase; + + button { + background-color: transparent; + border: none; + color: $gray-light; + text-transform: uppercase; + } + } + + .box-content { + background: $box-background-color; + border-radius: $border-radius; + box-shadow: 0 2px 2px 0 rgba(0,0,0,0.14), 0 3px 1px -2px rgba(0,0,0,0.12), 0 1px 5px 0 rgba(0,0,0,0.2); + + &.box-content-padded { + padding: 10px 15px; + } + + .box-content-row { + display: block; + padding: 10px 15px; + position: relative; + z-index: 1; + + &:before { + content: ""; + position: absolute; + right: 0; + bottom: 0; + height: 1px; + width: calc(100% - 10px); + border-bottom: 1px solid $box-border-color; + } + + &:first-child, &:last-child { + border-radius: $border-radius; + } + + &:last-child { + &:before { + border: none; + height: 0; + } + } + + &:after { + content: ""; + display: table; + clear: both; + } + + &:hover, &:focus, &.active { + background-color: $box-background-hover-color; + } + + &.pre { + white-space: pre; + overflow-x: auto; + } + + .row-label, label { + font-size: $font-size-small; + color: $text-muted; + display: block; + width: 100%; + margin-bottom: 5px; + } + + .text, .detail { + display: block; + color: $text-color; + } + + .detail { + font-size: $font-size-small; + color: $text-muted; + } + + .img-right { + float: right; + margin-left: 10px; + } + + .row-main { + flex-grow: 1; + } + + &.box-content-row-flex, &.box-content-row-checkbox, &.box-content-row-input, + &.box-content-row-slider, &.box-content-row-multi { + display: flex; + align-items: center; + word-break: break-word; + } + + &.box-content-row-multi { + width: 100%; + + input:not([type="checkbox"]) { + width: 100%; + } + + input + label.sr-only + select { + margin-top: 5px; + } + + > a { + padding: 8px 8px 8px 4px; + color: $brand-danger; + margin: 0; + } + } + + &.box-content-row-checkbox, &.box-content-row-input, &.box-content-row-slider { + label, .row-label { + font-size: $font-size-base; + color: $text-color; + display: inline; + width: initial; + margin-bottom: 0; + } + + > span { + color: $text-muted; + } + + > input { + margin: 0 0 0 auto; + padding: 0; + } + + > * { + margin-right: 15px; + + &:last-child { + margin-right: 0; + } + } + } + + &.box-content-row-input { + label { + white-space: nowrap; + } + + input { + text-align: right; + } + } + + &.box-content-row-slider { + input[type="range"] { + height: 10px; + } + + input[type="number"] { + width: 45px; + } + + label { + white-space: nowrap; + } + } + + input:not([type="checkbox"]), textarea { + border: none; + width: 100%; + background-color: transparent; + + &::-webkit-input-placeholder { + color: lighten($gray-light, 35%); + } + + &:focus { + outline: none; + } + } + + select { + width: 100%; + border: 1px solid darken($border-color-dark, 7%); + border-radius: $border-radius; + } + + .action-buttons { + display: flex; + margin-left: 5px; + + .row-btn { + cursor: pointer; + padding: 10px 8px; + background: none; + border: none; + color: $brand-primary; + + &:hover, &:focus { + color: darken($brand-primary, 10%); + } + + &.disabled { + color: $list-icon-color; + + &:hover { + color: $list-icon-color; + } + } + + &:last-child { + padding-right: 2px !important; + } + } + + &.no-pad .row-btn { + padding-top: 0; + padding-bottom: 0; + } + } + + select.field-type { + margin: 5px 0 0 25px; + width: calc(100% - 25px); + } + + .row-sub-icon { + color: $list-icon-color; + } + + .row-sub-label { + margin: 0 15px; + color: $gray-light; + white-space: nowrap; + } + } + + &.condensed .box-content-row, .box-content-row.condensed { + padding-top: 5px; + padding-bottom: 5px; + } + + &.no-hover .box-content-row, .box-content-row.no-hover { + &:hover, &:focus { + background-color: initial; + } + } + } + + .box-footer { + margin: 5px 10px; + font-size: $font-size-small; + color: $text-muted; + } +} diff --git a/src/scss/buttons.scss b/src/scss/buttons.scss new file mode 100644 index 00000000..1aadad7c --- /dev/null +++ b/src/scss/buttons.scss @@ -0,0 +1,70 @@ +@import "variables.scss"; + +.btn, #vault .footer button, .modal-footer button { + background-color: $button-backgound-color; + border-radius: $border-radius; + padding: 7px 15px; + border: 1px solid $button-border-color; + font-size: $font-size-base; + color: $button-color; + white-space: nowrap; + text-align: center; + cursor: pointer; + + &.primary { + color: $button-color-primary; + } + + &.danger { + color: $button-color-danger; + } + + &:hover:not([disabled]) { + cursor: pointer; + background-color: darken($button-backgound-color, 1.5%); + border-color: darken($button-border-color, 17%); + color: darken($button-color, 10%); + + &.primary { + color: darken($button-color-primary, 6%); + } + + &.danger { + color: darken($button-color-danger, 6%); + } + } + + &:focus:not([disabled]) { + cursor: pointer; + background-color: darken($button-backgound-color, 6%); + border-color: darken($button-border-color, 25%); + outline: 0; + } + + &[disabled] { + opacity: 0.65; + cursor: default !important; + } + + &.block { + display: block; + width: 100%; + } + + &.link { + border: none !important; + background: none !important; + + &:focus { + text-decoration: underline; + } + } +} + +.action-buttons { + .btn { + &:focus { + outline: auto; + } + } +} diff --git a/src/scss/environment.scss b/src/scss/environment.scss new file mode 100644 index 00000000..95ce9ffa --- /dev/null +++ b/src/scss/environment.scss @@ -0,0 +1,7 @@ +@import "variables.scss"; + +html.os_windows { + body { + border-top: 1px solid $border-color-dark; + } +} diff --git a/src/scss/list.scss b/src/scss/list.scss new file mode 100644 index 00000000..a0e1becf --- /dev/null +++ b/src/scss/list.scss @@ -0,0 +1,76 @@ +@import "variables.scss"; + +.list > a { + display: block; + padding: 3px 10px; + background-color: white; + text-decoration: none; + color: $text-color; + position: relative; + z-index: 1; + + &:after { + content: ""; + display: table; + clear: both; + } + + &:before { + content: ""; + position: absolute; + right: 0; + bottom: 0; + height: 1px; + width: calc(100% - 10px); + border-bottom: 1px solid $border-color; + } + + &:last-child:before { + border: none; + height: 0; + } + + &:hover, &:focus, &.active { + background-color: $list-item-hover; + } + + &.active { + border-left: 5px solid $brand-primary; + padding-left: 5px; + } + + &:focus:not(.active) { + border-left: 5px solid $text-muted; + padding-left: 5px; + } + + .text, .detail { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + display: block; + color: $text-color; + } + + .detail { + font-size: $font-size-small; + color: $gray-light; + } + + .icon { + display: flex; + justify-content: center; + align-items: center; + float: left; + height: 36px; + width: 34px; + margin-left: -5px; + color: $text-muted; + + img { + border-radius: $border-radius; + max-height: 20px; + max-width: 20px; + } + } +} diff --git a/src/scss/misc.scss b/src/scss/misc.scss new file mode 100644 index 00000000..57f9454a --- /dev/null +++ b/src/scss/misc.scss @@ -0,0 +1,188 @@ +@import "variables.scss"; + +small { + font-size: $font-size-small; +} + +.text-primary { + color: $brand-primary !important; +} + +.text-success { + color: $brand-success !important; +} + +.text-muted { + color: $text-muted !important; +} + +.text-default { + color: $text-color !important; +} + +.text-center { + text-align: center; +} + +.no-margin { + margin: 0 !important; +} + +p.lead { + font-size: $font-size-large; + margin-bottom: 20px; + font-weight: normal; +} + +[hidden] { + display: none !important; +} + +.monospaced { + font-family: $font-family-monospace; +} + +.sr-only { + position: absolute !important; + width: 1px !important; + height: 1px !important; + padding: 0 !important; + margin: -1px !important; + overflow: hidden !important; + clip: rect(0, 0, 0, 0) !important; + border: 0 !important; +} + +.totp { + .totp-code { + font-family: $font-family-monospace; + font-size: 1.1em; + } + + .totp-countdown { + margin: 3px 3px 0 0; + display: block; + user-select: none; + + .totp-sec { + font-size: 0.85em; + position: absolute; + line-height: 32px; + width: 32px; + text-align: center; + } + + svg { + width: 32px; + height: 32px; + transform: rotate(-90deg); + } + + .totp-circle { + stroke: $brand-primary; + fill: none; + + &.inner { + stroke-width: 3; + stroke-dasharray: 78.6; + stroke-dashoffset: 0; + } + + &.outer { + stroke-width: 2; + stroke-dasharray: 88; + stroke-dashoffset: 0; + } + } + } + + &.low { + .totp-sec, .totp-code { + color: $brand-danger; + } + + .totp-circle { + stroke: $brand-danger; + } + } +} + +.password-block { + font-size: $font-size-large; + word-break: break-all; + font-family: $font-family-monospace; + min-height: 60px; + display: flex; + align-items: center; + justify-content: center; + text-align: center; + + .modal-body & { + margin-top: 10px; + } +} + +#duo-frame { + background: url('../images/loading.svg') 0 0 no-repeat; + height: 330px; + margin: 0 -150px 15px -150px; + + iframe { + width: 100%; + height: 100%; + border: none; + } +} + +form, .form { + .form-group { + margin-bottom: 10px; + + &:last-child { + margin-bottom: 0; + } + + label { + display: inline-block; + margin-bottom: 2px; + } + + input, select, textarea { + border: 1px solid darken($border-color-dark, 7%); + border-radius: $border-radius; + display: block; + } + } + + .checkbox { + position: relative; + display: block; + padding-left: 18px; + + label { + margin-bottom: 0; + } + + input[type="checkbox"] { + position: absolute; + margin-top: 4px; + margin-left: -18px; + } + } + + .help-block { + margin-top: 3px; + color: $text-muted; + display: block; + } +} + +app-root > #loading { + display: flex; + text-align: center; + justify-content: center; + align-items: center; + height: 100%; + width: 100%; + color: $text-muted; +} diff --git a/src/scss/modal.scss b/src/scss/modal.scss new file mode 100644 index 00000000..fe418945 --- /dev/null +++ b/src/scss/modal.scss @@ -0,0 +1,338 @@ +@import "variables.scss"; + +$white: white; +$black: black; +$line-height-base: 14px; +$border-radius-lg: $border-radius; + +// ref: https://github.com/twbs/bootstrap/blob/v4-dev/scss/_variables.scss + +$grid-breakpoints: ( xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px ) !default; + +$zindex-modal-backdrop: 1040 !default; +$zindex-modal: 1050 !default; + +// Padding applied to the modal body +$modal-inner-padding: 10px !default; + +$modal-dialog-margin: .5rem !default; +$modal-dialog-margin-y-sm-up: 1.75rem !default; + +$modal-title-line-height: $line-height-base !default; + +$modal-content-bg: $background-color-alt !default; +$modal-content-border-color: rgba($black, .2) !default; +$modal-content-border-width: 1px !default; +$modal-content-box-shadow-xs: none; +$modal-content-box-shadow-sm-up: none; + +$modal-backdrop-bg: $black !default; +$modal-backdrop-opacity: .5 !default; +$modal-header-border-color: $border-color-dark !default; +$modal-footer-border-color: $modal-header-border-color !default; +$modal-header-border-width: $modal-content-border-width !default; +$modal-footer-border-width: $modal-header-border-width !default; +$modal-header-padding: 12px !default; + +$modal-lg: 800px !default; +$modal-md: 500px !default; +$modal-sm: 300px !default; + +$modal-transition: transform .3s ease-out !default; + +$close-font-size: $font-size-base * 1.5 !default; +$close-font-weight: bold !default; +$close-color: $black !default; +$close-text-shadow: 0 1px 0 $white !default; + +// ref: https://github.com/twbs/bootstrap/blob/v4-dev/scss/mixins/_breakpoints.scss + +@mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints) { + $min: breakpoint-min($name, $breakpoints); + + @if $min { + @media (min-width: $min) { + @content; + } + } + @else { + @content; + } +} + +@function breakpoint-min($name, $breakpoints: $grid-breakpoints) { + $min: map-get($breakpoints, $name); + @return if($min != 0, $min, null); +} + +// Custom Added CSS animations + +@keyframes modalshow { + 0% { + opacity: 0; + transform: translate(0, -25%); + } + + 100% { + opacity: 1; + transform: translate(0, 0); + } +} + +@keyframes backdropshow { + 0% { + opacity: 0; + } + + 100% { + opacity: $modal-backdrop-opacity; + } +} + +// ref: https://github.com/twbs/bootstrap/blob/v4-dev/scss/_modal.scss + +// .modal-open - body class for killing the scroll +// .modal - container to scroll within +// .modal-dialog - positioning shell for the actual modal +// .modal-content - actual modal w/ bg and corners and stuff + + +// Kill the scroll on the body +.modal-open { + overflow: hidden; +} + +// Container that the modal scrolls within +.modal { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: $zindex-modal; + //display: none; + overflow: hidden; + // Prevent Chrome on Windows from adding a focus outline. For details, see + // https://github.com/twbs/bootstrap/pull/10951. + outline: 0; + // We deliberately don't use `-webkit-overflow-scrolling: touch;` due to a + // gnarly iOS Safari bug: https://bugs.webkit.org/show_bug.cgi?id=158342 + // See also https://github.com/twbs/bootstrap/issues/17695 + .modal-open & { + overflow-x: hidden; + overflow-y: auto; + } +} + +// Shell div to position the modal with bottom padding +.modal-dialog { + position: relative; + width: auto; + margin: $modal-dialog-margin; + // allow clicks to pass through for custom click handling to close modal + pointer-events: none; + // When fading in the modal, animate it to slide down + .modal.fade & { + //@include transition($modal-transition); + //transform: translate(0, -25%); + animation: modalshow 0.3s ease-in; + } + //.modal.show & { + // transform: translate(0, 0); + //} + transform: translate(0, 0); +} + +.modal-dialog-centered { + display: flex; + align-items: center; + min-height: calc(100% - (#{$modal-dialog-margin} * 2)); +} + +// Actual modal +.modal-content { + position: relative; + display: flex; + flex-direction: column; + width: 100%; // Ensure `.modal-content` extends the full width of the parent `.modal-dialog` + // counteract the pointer-events: none; in the .modal-dialog + pointer-events: auto; + background-color: $modal-content-bg; + background-clip: padding-box; + border: $modal-content-border-width solid $modal-content-border-color; + //@include border-radius($border-radius-lg); + //@include box-shadow($modal-content-box-shadow-xs); + border-radius: $border-radius-lg; + box-shadow: $modal-content-box-shadow-xs; + // Remove focus outline from opened modal + outline: 0; +} + +// Modal background +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: $zindex-modal-backdrop; + background-color: $modal-backdrop-bg; + // Fade for backdrop + &.fade { + //opacity: 0; + animation: backdropshow 0.1s ease-in; + } + //&.show { + // opacity: $modal-backdrop-opacity; + //} + opacity: $modal-backdrop-opacity; +} + +// Modal header +// Top section of the modal w/ title and dismiss +.modal-header { + display: flex; + align-items: flex-start; // so the close btn always stays on the upper right corner + justify-content: space-between; // Put modal header elements (title and dismiss) on opposite ends + padding: $modal-header-padding $modal-inner-padding; + border-bottom: $modal-header-border-width solid $modal-header-border-color; + //@include border-top-radius($border-radius-lg); + + .close { + padding: $modal-header-padding $modal-inner-padding; + // auto on the left force icon to the right even when there is no .modal-title + margin: (-$modal-header-padding) (-$modal-inner-padding) (-$modal-header-padding) auto; + } + + h5 { + font-size: $font-size-base; + font-weight: bold; + display: flex; + align-items: center; + + .fa { + margin-right: 5px; + } + } +} + +// Title text within header +.modal-title { + margin-bottom: 0; + line-height: $modal-title-line-height; +} + +// Modal body +// Where all modal content resides (sibling of .modal-header and .modal-footer) +.modal-body { + position: relative; + // Enable `flex-grow: 1` so that the body take up as much space as possible + // when should there be a fixed height on `.modal-dialog`. + flex: 1 1 auto; + padding: $modal-inner-padding; +} + +// Footer (for actions) +.modal-footer { + display: flex; + align-items: center; // vertically center + //justify-content: flex-end; // Right align buttons with flex property because text-align doesn't work on flex items + padding: $modal-inner-padding; + border-top: $modal-footer-border-width solid $modal-footer-border-color; + // Easily place margin between footer elements + button { + margin-right: 10px; + + &:last-child { + margin-right: 0; + } + } + + .right { + margin-left: auto; + display: flex; + } +} + +// Measure scrollbar width for padding body during modal show/hide +.modal-scrollbar-measure { + position: absolute; + top: -9999px; + width: 50px; + height: 50px; + overflow: scroll; +} + +// Scale up the modal +@include media-breakpoint-up(sm) { + // Automatically set modal's width for larger viewports + .modal-dialog { + max-width: $modal-md; + margin: $modal-dialog-margin-y-sm-up auto; + } + + .modal-dialog-centered { + min-height: calc(100% - (#{$modal-dialog-margin-y-sm-up} * 2)); + } + + .modal-content { + //@include box-shadow($modal-content-box-shadow-sm-up); + box-shadow: $modal-content-box-shadow-sm-up; + } + + .modal-sm { + max-width: $modal-sm; + } +} + +@include media-breakpoint-up(lg) { + .modal-lg { + max-width: $modal-lg; + } +} + +// ref: https://github.com/twbs/bootstrap/blob/v4-dev/scss/_close.scss + +.close { + float: right; + font-size: $close-font-size; + font-weight: $close-font-weight; + line-height: 1; + color: $close-color; + text-shadow: $close-text-shadow; + opacity: .5; + + &:hover, &:focus { + color: $close-color; + text-decoration: none; + opacity: .75; + } + // Opinionated: add "hand" cursor to non-disabled .close elements + &:not(:disabled):not(.disabled) { + cursor: pointer; + } +} + +// Additional properties for button version +// iOS requires the button element instead of an anchor tag. +// If you want the anchor version, it requires `href="#"`. +// See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile + +// stylelint-disable property-no-vendor-prefix, selector-no-qualifying-type +button.close { + padding: 0; + background-color: transparent; + border: 0; + -webkit-appearance: none; +} +// stylelint-enable + +// box + +.modal-content .box { + margin-top: 20px; + + &:first-child { + margin-top: 0; + } +} diff --git a/src/scss/pages.scss b/src/scss/pages.scss new file mode 100644 index 00000000..aa0663e4 --- /dev/null +++ b/src/scss/pages.scss @@ -0,0 +1,118 @@ +@import "variables.scss"; + +#login-page, #lock-page { + display: flex; + justify-content: center; + align-items: center; + height: 100%; + + @media (min-height: 500px) { + height: calc(100% + 50px); + margin-top: -50px; + } + + @media (min-height: 800px) { + height: calc(100% + 300px); + margin-top: -300px; + } + + img { + margin: 0 auto 15px; + width: 282px; + display: block; + } +} + +#register-page, #hint-page, #two-factor-page { + padding-top: 20px; + + .content { + margin: 0 auto; + } + + img { + margin-bottom: 10px; + max-width: 100%; + height: auto; + display: block; + border-radius: $border-radius; + } +} + +#login-page, #register-page, #hint-page, #two-factor-page, #lock-page { + .content { + width: 300px; + + p { + text-align: center + } + + p.lead, h1 { + font-size: $font-size-large; + text-align: center; + margin-bottom: 20px; + font-weight: normal; + } + + .box { + margin-bottom: 20px; + + &.last { + margin-bottom: 15px; + } + } + + .buttons { + display: flex; + margin-bottom: 20px; + + button { + margin-right: 10px; + + &:last-child { + margin-right: 0; + } + } + } + + .sub-options { + text-align: center; + margin-bottom: 20px; + + a { + display: block; + margin-bottom: 10px; + + &:last-child { + margin-bottom: 0; + } + } + } + + a.settings-icon { + color: #bbbbbb; + position: absolute; + top: 10px; + left: 10px; + + span { + visibility: hidden; + } + + &:hover, &:focus { + color: $brand-primary; + text-decoration: none; + + span { + visibility: visible; + } + } + } + } +} + +#register-page { + .content { + width: 400px; + } +} diff --git a/src/scss/plugins.scss b/src/scss/plugins.scss new file mode 100644 index 00000000..82044499 --- /dev/null +++ b/src/scss/plugins.scss @@ -0,0 +1,75 @@ +$fa-font-path: "~font-awesome/fonts"; +@import "~font-awesome/scss/font-awesome.scss"; +@import "~angular2-toaster/toaster"; + +@import "variables.scss"; + +#toast-container { + .toast-close-button { + right: -0.15em; + } + + .toast { + opacity: 1 !important; + background-image: none !important; + border-radius: $border-radius; + box-shadow: 0 0 8px rgba(0, 0, 0, 0.35); + display: flex; + align-items: center; + + &:hover { + box-shadow: 0 0 10px rgba(0, 0, 0, 0.6); + } + + &:before { + font-family: FontAwesome; + font-size: 25px; + line-height: 20px; + float: left; + color: #ffffff; + padding-right: 10px; + margin: auto 0 auto -36px; + } + + .toaster-icon { + display: none; + } + + &.toast-danger, &.toast-error { + background-image: none !important; + background-color: $brand-danger; + + &:before { + content: "\f0e7"; + margin-left: -30px; + } + } + + &.toast-warning { + background-image: none !important; + background-color: $brand-warning; + + &:before { + content: "\f071"; + } + } + + &.toast-info { + background-image: none !important; + background-color: $brand-info; + + &:before { + content: "\f05a"; + } + } + + &.toast-success { + background-image: none !important; + background-color: $brand-success; + + &:before { + content: "\f00C"; + } + } + } +} diff --git a/src/scss/styles.scss b/src/scss/styles.scss new file mode 100644 index 00000000..f876ed31 --- /dev/null +++ b/src/scss/styles.scss @@ -0,0 +1,11 @@ +@import "variables.scss"; +@import "base.scss"; +@import "pages.scss"; +@import "vault.scss"; +@import "list.scss"; +@import "box.scss"; +@import "buttons.scss"; +@import "misc.scss"; +@import "modal.scss"; +@import "plugins.scss"; +@import "environment.scss"; diff --git a/src/scss/variables.scss b/src/scss/variables.scss new file mode 100644 index 00000000..15783351 --- /dev/null +++ b/src/scss/variables.scss @@ -0,0 +1,38 @@ +$font-family-sans-serif: 'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif; +$font-family-monospace: Menlo, Monaco, Consolas, "Courier New", monospace; +$font-size-base: 14px; +$font-size-large: 18px; +$font-size-small: 12px; +$text-color: #000000; +$background-color: #efeff4; +$border-color: #f0f0f0; +$border-color-dark: #ddd; +$list-item-hover: #fbfbfb; +$list-icon-color: #c7c7cd; +$border-radius: 3px; +$line-height-base: 1.42857143; + +$gray: #555; +$gray-light: #777; +$text-muted: $gray-light; + +$brand-primary: #3c8dbc; +$brand-danger: #dd4b39; +$brand-success: #00a65a; +$brand-info: #555555; +$brand-warning: #bf7e16; +$brand-primary-accent: #286090; + +$background-color: white; +$background-color-alt: #f9fafc; +$background-color-alt2: #ecf0f5; + +$box-background-color: $background-color; +$box-background-hover-color: $list-item-hover; +$box-border-color: $border-color; + +$button-border-color: darken($border-color-dark, 12%); +$button-backgound-color: white; +$button-color: lighten($text-color, 40%); +$button-color-primary: darken($brand-primary, 8%); +$button-color-danger: darken($brand-danger, 10%); diff --git a/src/scss/vault.scss b/src/scss/vault.scss new file mode 100644 index 00000000..c5bfbc9f --- /dev/null +++ b/src/scss/vault.scss @@ -0,0 +1,269 @@ +@import "variables.scss"; + +#vault { + height: 100%; + display: flex; + + > #groupings, > #items, > #details, > #logo { + display: flex; + flex-direction: column; + + .inner-content { + padding: 10px 15px; + } + } + + > #groupings { + background-color: $background-color-alt; + width: 22%; + min-width: 175px; + max-width: 250px; + border-right: 1px solid $border-color-dark; + + .inner-content { + padding-bottom: 0; + padding-right: 5px; + } + + h2 { + color: $gray-light; + text-transform: uppercase; + font-size: $font-size-base; + font-weight: normal; + margin-bottom: 5px; + display: flex; + + button { + margin-left: auto; + background: none; + border: none; + color: lighten($gray-light, 30%); + + &:hover, &:focus { + color: $gray-light; + cursor: pointer; + } + } + } + + ul:not(.fa-ul) { + li { + margin: 0; + padding: 0; + list-style: none; + } + } + + ul.fa-ul { + li { + .fa-li { + left: -11px; + top: 8px; + } + + a { + padding-left: 12px; + } + + &.active .fa-li { + left: 4px; + } + } + } + + ul { + padding: 0; + margin: 0 0 15px 0; + + li { + a { + padding: 5px 0; + color: $text-color; + display: flex; + align-items: center; + + span { + visibility: hidden; + margin-left: auto; + color: lighten($gray-light, 30%); + + &:hover { + color: $text-muted; + } + } + + &:hover, &:focus { + span { + visibility: visible; + } + } + } + + &.active { + background-color: darken($background-color-alt, 5%); + margin-left: -15px; + margin-right: -5px; + padding-left: 15px; + padding-right: 5px; + } + } + } + } + + > #items { + background-color: $background-color; + width: 28%; + min-width: 200px; + max-width: 350px; + border-right: 1px solid $border-color-dark; + + .no-items { + display: flex; + height: 100%; + flex-direction: column; + justify-content: center; + align-items: center; + text-align: center; + padding: 0 10px; + + .fa { + margin-bottom: 10px; + color: $list-icon-color; + } + } + } + + > #details { + background-color: $background-color-alt2; + flex: 1; + min-width: 0; + + .inner-content { + min-width: 400px; + } + + .box { + max-width: 550px; + margin: 30px auto 0 auto; + + &:first-child { + margin-top: 10px; + } + + &:last-child { + margin-bottom: 30px; + } + } + + > form { + display: flex; + flex-direction: column; + height: 100%; + } + } + + > #logo { + flex: 1; + min-width: 0; + + .content { + overflow-y: hidden; + overflow-x: auto; + } + + .inner-content { + min-width: 320px; + height: 100%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + } + + img { + width: 282px; + opacity: 0.3; + transition: all 1s ease-in-out; + + &:hover { + opacity: 1; + } + } + } + + .header { + min-height: 44px; + max-height: 44px; + background-color: $brand-primary; + flex: 0 0 auto; + border-bottom: 1px solid darken($brand-primary, 7%); + display: flex; + align-items: center; + + &.header-search { + .search { + padding: 0 7px; + width: 100%; + text-align: left; + position: relative; + + .fa { + position: absolute; + top: 7px; + left: 15px; + color: lighten($brand-primary, 30%); + } + + input { + width: 100%; + margin: 0; + background: darken($brand-primary, 8%); + border: none; + color: white; + padding: 5px 10px 5px 30px; + border-radius: $border-radius; + + &:focus { + border-radius: $border-radius; + outline: none; + background: darken($brand-primary, 10%); + } + + &::-webkit-input-placeholder { + color: lighten($brand-primary, 35%); + } + } + } + } + } + + .content { + flex: 1 1 auto; + position: relative; + overflow: auto; + height: 100%; + } + + .footer { + height: 50px; + background-color: $background-color-alt; + flex: 0 0 auto; + border-top: 1px solid $border-color-dark; + display: flex; + align-items: center; + padding: 0 15px; + + button { + margin-right: 10px; + + &:last-child { + margin-right: 0; + } + } + + .right { + margin-left: auto; + display: flex; + } + } +} diff --git a/tsconfig.json b/tsconfig.json index d30525b0..de1c84c6 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -14,7 +14,8 @@ "jslib/*": [ "jslib/src/*" ], "@angular/*": [ "node_modules/@angular/*" ], "angular2-toaster": [ "node_modules/angular2-toaster" ], - "angulartics2": [ "node_modules/angulartics2" ] + "angulartics2": [ "node_modules/angulartics2" ], + "electron": [ "node_modules/electron" ] } }, "exclude": [ @@ -22,6 +23,7 @@ "jslib/node_modules", "dist", "jslib/dist", - "build" + "build", + "jslib/spec" ] } diff --git a/webpack.main.js b/webpack.main.js new file mode 100644 index 00000000..7b159da8 --- /dev/null +++ b/webpack.main.js @@ -0,0 +1,66 @@ +const path = require('path'); +const webpack = require('webpack'); +const merge = require('webpack-merge'); +const CopyWebpackPlugin = require('copy-webpack-plugin'); +const CleanWebpackPlugin = require('clean-webpack-plugin'); +const nodeExternals = require('webpack-node-externals'); + +const common = { + module: { + rules: [ + { + test: /\.ts$/, + enforce: 'pre', + loader: 'tslint-loader' + }, + { + test: /\.tsx?$/, + use: 'ts-loader', + exclude: /node_modules\/(?!(@bitwarden)\/).*/ + }, + ] + }, + plugins: [], + resolve: { + extensions: ['.tsx', '.ts', '.js'], + alias: { + jslib: path.join(__dirname, 'jslib/src') + } + }, + output: { + filename: '[name].js', + path: path.resolve(__dirname, 'build') + } +}; + +const main = { + target: 'electron-main', + node: { + __dirname: false, + __filename: false + }, + entry: { + 'main': './src/main.ts' + }, + module: { + rules: [ + { + test: /\.node$/, + loader: 'node-loader' + }, + ] + }, + plugins: [ + new CleanWebpackPlugin([ + path.resolve(__dirname, 'build/*') + ]), + new CopyWebpackPlugin([ + './src/package.json', + { from: './src/images', to: 'images' }, + { from: './src/locales', to: 'locales' }, + ]), + ], + externals: [nodeExternals()] +}; + +module.exports = merge(common, main); diff --git a/webpack.renderer.js b/webpack.renderer.js new file mode 100644 index 00000000..4a8894fc --- /dev/null +++ b/webpack.renderer.js @@ -0,0 +1,144 @@ +const path = require('path'); +const webpack = require('webpack'); +const merge = require('webpack-merge'); +const HtmlWebpackPlugin = require('html-webpack-plugin'); +const GoogleFontsPlugin = require("google-fonts-webpack-plugin"); +const ExtractTextPlugin = require('extract-text-webpack-plugin'); +const AngularCompilerPlugin = require('@ngtools/webpack').AngularCompilerPlugin; + +const isVendorModule = (module) => { + if (!module.context) { + return false; + } + return module.context.indexOf('node_modules') !== -1; +}; + +const extractCss = new ExtractTextPlugin({ + filename: '[name].css', + disable: false, + allChunks: true +}); + +const common = { + module: { + rules: [ + { + test: /\.ts$/, + enforce: 'pre', + loader: 'tslint-loader' + }, + { + test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/, + loader: '@ngtools/webpack' + }, + { + test: /\.(jpe?g|png|gif|svg)$/i, + exclude: /.*(fontawesome-webfont)\.svg/, + use: [{ + loader: 'file-loader', + options: { + name: '[name].[ext]', + outputPath: 'images/', + } + }] + } + ] + }, + plugins: [], + resolve: { + extensions: ['.tsx', '.ts', '.js'], + alias: { + jslib: path.join(__dirname, 'jslib/src') + }, + symlinks: false, + modules: [path.resolve('node_modules')] + }, + output: { + filename: '[name].js', + path: path.resolve(__dirname, 'build') + } +}; + +const renderer = { + target: 'electron-renderer', + node: { + __dirname: false + }, + entry: { + 'app/main': './src/app/main.ts' + }, + module: { + rules: [ + { + test: /\.(html)$/, + loader: 'html-loader' + }, + { + test: /.(ttf|otf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/, + exclude: /loading.svg/, + use: [{ + loader: 'file-loader', + options: { + name: '[name].[ext]', + outputPath: 'fonts/', + publicPath: '../' + } + }] + }, + { + test: /\.scss$/, + use: extractCss.extract({ + use: [ + { + loader: 'css-loader', + }, + { + loader: 'sass-loader', + } + ], + publicPath: '../' + }) + }, + ] + }, + plugins: [ + new GoogleFontsPlugin({ + fonts: [ + { + family: 'Open Sans', + variants: ['300', '300italic', '400', '400italic', '600', '600italic', + '700', '700italic', '800', '800italic'], + subsets: ['cyrillic', 'cyrillic-ext', 'greek', 'greek-ext', 'latin', 'latin-ext'] + } + ], + formats: ['woff2'], + path: 'fonts/', + filename: 'css/fonts.css' + }), + new AngularCompilerPlugin({ + tsConfigPath: 'tsconfig.json', + entryModule: 'src/app/app.module#AppModule', + sourceMap: true + }), + // ref: https://github.com/angular/angular/issues/20357 + new webpack.ContextReplacementPlugin(/\@angular(\\|\/)core(\\|\/)esm5/, + path.resolve(__dirname, './src')), + new webpack.optimize.CommonsChunkPlugin({ + name: 'app/vendor', + chunks: ['app/main'], + minChunks: isVendorModule + }), + new HtmlWebpackPlugin({ + template: './src/index.html', + filename: 'index.html', + chunks: ['app/vendor', 'app/main'] + }), + new webpack.SourceMapDevToolPlugin({ + filename: '[name].js.map', + include: ['app/main.js'] + }), + extractCss + ] +}; + +module.exports = merge(common, renderer);