From 7b55a70a3673fc76ee6ff9e50577ca72536606fd Mon Sep 17 00:00:00 2001 From: mtgto Date: Fri, 22 May 2020 00:53:44 +0900 Subject: [PATCH] feat: Add Secure Keyboard Entry APIs in macOS (#20678) * feat: Add Secure Keyboard Entry APIs in macOS Add methods: - app.isSecureInputEnabled() - app.setSecureInputEnabled(enabled) These enable to prevent other process listens keyboard input events. * fix: lint error in app.md for #20678 * fix: crash app.setSecureInputEnabled() in password textfield * fix: export Secure keyboard Entry API to only macOS * fix: lint error in browser_mac.mm for #20678 * test: add test for app.setSecureKeyboardEntryEnabled in macOS --- docs/api/app.md | 19 +++++++++++++++++++ shell/browser/api/electron_api_app.cc | 8 ++++++++ shell/browser/browser.h | 14 ++++++++++++++ shell/browser/browser_mac.mm | 14 ++++++++++++++ spec-main/api-app-spec.ts | 9 +++++++++ 5 files changed, 64 insertions(+) diff --git a/docs/api/app.md b/docs/api/app.md index e234d5a6d5ab..283988307bac 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -1304,6 +1304,25 @@ app.moveToApplicationsFolder({ Would mean that if an app already exists in the user directory, if the user chooses to 'Continue Move' then the function would continue with its default behavior and the existing app will be trashed and the active app moved into its place. +### `app.isSecureKeyboardEntryEnabled()` _macOS_ + +Returns `Boolean` - whether `Secure Keyboard Entry` is enabled. + +By default this API will return `false`. + +### `app.setSecureKeyboardEntryEnabled(enabled)` _macOS_ + +* `enabled` Boolean - Enable or disable `Secure Keyboard Entry` + +Set the `Secure Keyboard Entry` is enabled in your application. + +By using this API, important information such as password and other sensitive information can be prevented from being intercepted by other processes. + +See [Apple's documentation](https://developer.apple.com/library/archive/technotes/tn2150/_index.html) for more +details. + +**Note:** Enable `Secure Keyboard Entry` only when it is needed and disable it when it is no longer needed. + ## Properties ### `app.accessibilitySupportEnabled` _macOS_ _Windows_ diff --git a/shell/browser/api/electron_api_app.cc b/shell/browser/api/electron_api_app.cc index 5ca71f785c47..9ca9a7ad0dd6 100644 --- a/shell/browser/api/electron_api_app.cc +++ b/shell/browser/api/electron_api_app.cc @@ -1525,6 +1525,14 @@ void App::BuildPrototype(v8::Isolate* isolate, base::BindRepeating(&Browser::SetAboutPanelOptions, browser)) .SetMethod("showAboutPanel", base::BindRepeating(&Browser::ShowAboutPanel, browser)) +#if defined(OS_MACOSX) + .SetMethod( + "isSecureKeyboardEntryEnabled", + base::BindRepeating(&Browser::IsSecureKeyboardEntryEnabled, browser)) + .SetMethod( + "setSecureKeyboardEntryEnabled", + base::BindRepeating(&Browser::SetSecureKeyboardEntryEnabled, browser)) +#endif #if defined(OS_MACOSX) || defined(OS_WIN) .SetMethod("showEmojiPanel", base::BindRepeating(&Browser::ShowEmojiPanel, browser)) diff --git a/shell/browser/browser.h b/shell/browser/browser.h index 4fbab02d8c42..0cce2b275080 100644 --- a/shell/browser/browser.h +++ b/shell/browser/browser.h @@ -23,6 +23,10 @@ #include "base/files/file_path.h" #endif +#if defined(OS_MACOSX) +#include "ui/base/cocoa/secure_password_input.h" +#endif + namespace base { class FilePath; } @@ -261,6 +265,12 @@ class Browser : public WindowListObserver { void RemoveObserver(BrowserObserver* obs) { observers_.RemoveObserver(obs); } +#if defined(OS_MACOSX) + // Returns whether secure input is enabled + bool IsSecureKeyboardEntryEnabled(); + void SetSecureKeyboardEntryEnabled(bool enabled); +#endif + bool is_shutting_down() const { return is_shutdown_; } bool is_quiting() const { return is_quiting_; } bool is_ready() const { return is_ready_; } @@ -305,6 +315,10 @@ class Browser : public WindowListObserver { std::unique_ptr> ready_promise_; +#if defined(OS_MACOSX) + std::unique_ptr password_input_enabler_; +#endif + #if defined(OS_LINUX) || defined(OS_WIN) base::Value about_panel_options_; #elif defined(OS_MACOSX) diff --git a/shell/browser/browser_mac.mm b/shell/browser/browser_mac.mm index b51860340e48..ec0f832479ef 100644 --- a/shell/browser/browser_mac.mm +++ b/shell/browser/browser_mac.mm @@ -4,6 +4,7 @@ #include "shell/browser/browser.h" +#include #include #include @@ -430,4 +431,17 @@ bool Browser::IsEmojiPanelSupported() { return true; } +bool Browser::IsSecureKeyboardEntryEnabled() { + return password_input_enabler_.get() != nullptr; +} + +void Browser::SetSecureKeyboardEntryEnabled(bool enabled) { + if (enabled) { + password_input_enabler_ = + std::make_unique(); + } else { + password_input_enabler_.reset(); + } +} + } // namespace electron diff --git a/spec-main/api-app-spec.ts b/spec-main/api-app-spec.ts index a3ffe1be2721..f6e785c91567 100644 --- a/spec-main/api-app-spec.ts +++ b/spec-main/api-app-spec.ts @@ -1439,6 +1439,15 @@ describe('app module', () => { expect(getSwitchValue).to.equal(''); }); }); + + ifdescribe(process.platform === 'darwin')('app.setSecureKeyboardEntryEnabled', () => { + it('changes Secure Keyboard Entry is enabled', () => { + app.setSecureKeyboardEntryEnabled(true); + expect(app.isSecureKeyboardEntryEnabled()).to.equal(true); + app.setSecureKeyboardEntryEnabled(false); + expect(app.isSecureKeyboardEntryEnabled()).to.equal(false); + }); + }); }); describe('default behavior', () => {