166 Commits

Author SHA1 Message Date
Michael Starke
9851a7b4e2 Use switch case. Localise user facing texts 2021-07-22 17:43:17 +02:00
Julius Zint
d1690d76d1 Extracted the logic for storing the encrypted compositekey into a
seperate class
2021-03-14 15:54:42 +01:00
Julius Zint
3c54cd9d7a Code refactoring to implement suggestions from the code review.
Binding the touchIdEnabled Buttons state directly to the userdefaults
value.

Fixed bug that disabled the TouchIdEnabled button on an unsucessfull
TouchId unlock
2021-02-21 12:48:04 +01:00
Julius Zint
4aa812740f Code refactoring to implement suggestions from the code review.
Renamed touchIdEnabled outlet to touchIdEnabledButton in preparation
to bind a variable to the state value.

Used SecKeyCreateRandomKey instead of SecKeyGeneratePair as suggested
by the headers.
2021-02-21 12:04:49 +01:00
Julius Zint
197a4145e8 Code refactoring to implement suggestions from the code review.
The fileURL for the current document does no longer have to be passed
in as a parameter but instead is retreived by accessing the windowControllers
document that hosts the MPPasswordInputController.

_touchIdHandleUnlockAttempt got renamed to _touchIdUpdateKeyForCurrentDocument
to better state its actual purpose and should no longer be called
on unsuccessfull unlock attempts. It also now removes stored keys if the
state of the TouchIdEnabled button has changed.

The key, that is derived from the document, is now the same whether it is
used to store it in the transient dictionary or the userdefaults
2021-02-21 11:27:41 +01:00
Julius Zint
88a5af995e Small layout changes. This prevents the error message overlapping
the TouchID enabled button.
2021-02-14 17:58:06 +01:00
Julius Zint
7b79c0b814 Added tooltip to TouchID enabled button. This is a first attempt
to make it better to understand what the mixed state is all about.
2021-02-14 17:56:29 +01:00
Julius Zint
c5e30a0fa0 The TouchID keypair can no be removed from the macOS keychain
This is a good feature for security and stability. It gives users
the option to prevent TouchID unlock for any previously unlocked
database and it is also helpful in cases where only one part of the
keypair is in the macOS keychain.
2021-02-14 17:40:11 +01:00
Julius Zint
9d058f9d15 Explicitly setting the keychain-access-groups. In these groups Keychain
items can be shared. If left empty, Xcode inserts the AppID prefix with
a wildcard.
2021-02-14 10:00:15 +01:00
Julius Zint
33907e07d6 Removed script buildstep that is no longer needed 2021-02-14 10:00:15 +01:00
Julius Zint
02b3fc2945 Fixed errors while rebasing to latest master 2021-02-14 10:00:15 +01:00
Julius Zint
484b5e4acd Added a flag to support unlocking the database with the apple watch as well as TouchID 2021-02-14 10:00:15 +01:00
Julius Zint
82558936da Fixed typo 2021-02-14 10:00:15 +01:00
Julius Zint
92a120c405 Support for persistent TouchID unlock.
While originally not intended, this changeset enables MacPass to
unlock a database with TouchID even after the process is completly
wiped.

It does this by introducing multiple modes of operation.

First:  TouchId can be completly disabled. The TouchID checkbox is off
        and MacPass works like the TouchID feature had never been added.

Second: The TouchID checkbox gets put into the mixed state. MacPass will now
        remember the database key in memory as long as the process remains
	alive and the database can be unlocked with TouchID until the
	applications terminates.

Third: The TouchID checkbox is checked and MacPass will store the encrypted
       database key on a successfull unlock attempt in the standard
       userdefaults. TouchID unlock works now even after MacPass is completly
       terminated and restarted.
2021-02-14 10:00:15 +01:00
Julius Zint
3fc73a7fd9 Switched Encryption algorithm to support larger message texts.
kSecKeyAlgorithmRSAEncryptionOAEPSHA256AESGCM is now used. Apples CryptoKit makes
it very easy to use asymmetric cryptography to encrypt a symmetric key and with it
encrypt a message. So now the Database key material is no longer directly encrypted
with the asymmetric key but with a randomly generated symmetric one.
2021-02-14 10:00:15 +01:00
Julius Zint
431b636057 Switched to archiving the complete composite key for TouchID unlock 2021-02-14 10:00:15 +01:00
Julius Zint
51bdf12198 MPPasswordInputController completion callback refactoring
Changed the completion callback definition to take a KPKCompositeKey pointer
instead of a password string and keyfile URL. This is a intermedate step to
support key files with TouchID unlock. The next step is to make
KPKCompositeKey conform to the NSCoding protocol. The serialized data can
then be stored instead of the password.
2021-02-14 10:00:15 +01:00
Julius Zint
700dd43282 TouchID unlock is now optional
Added a CheckBox to the PasswordInput view, so the user can see and
manipulate, whether the TouchID feature is enabled or disabled. The
choice is remembered in the standard user defaults.
2021-02-14 10:00:15 +01:00
Julius Zint
5157ec823f Enables TouchID unlock for multiple Database files.
This changeset adds the optional fileURL parameter to the
requestPasswordWithMessage function in MPPasswordInputController.
The controller uses this URL as a key to store the encrypted
masterpassword in a dictionary.

In my opinion edge cases like when a file is moved or replaced
do not have to get special handling since the worst case scenario
is that TouchID unlock does not work and users have still the
option to unlock with the masterpassword.

Also this changeset removes the unused
requestPasswordWithCompletionHandler function
2021-02-14 10:00:15 +01:00
Julius Zint
94956a673b fixed typos 2021-02-14 10:00:15 +01:00
Julius Zint
4e56740577 Added necessary entitlement and additional buildstep
Enabled the "Keychain Sharing" Entitlement that is required for
the Keychain APIs to work properly.

The additional buildstep signs the KissXML.framework nested inside
the KeePassKit.framework before this Framework itself is signed and
embedded. This is necessary because, to my knowledge, Xcode does not
support signing nested frameworks.
2021-02-14 10:00:15 +01:00
Julius Zint
a7b8be1886 TouchID unlock Feature for MacPass.
To use it a user must first enter the correct password for the database.
If the unlock succeeds, the supplied password is encrypted with the public
part of a RSA keypair. On subsequent unlocks a TouchID button appears. If
clicked, MacPass queries the Keychain for the private key part and uses it to
decrypt the previously supplied password and tries to unlock the database
with it.
2021-02-14 10:00:15 +01:00
Michael Starke
4addd907d4 Directly set cell class for HNUISecureTextField 2021-02-10 20:21:20 +01:00
Michael Starke
7ef88b7e88 Fixed duplicated entry not being selected in in entry table view. 2021-02-10 15:47:13 +01:00
Michael Starke
b19a79095a Added settings to disable password generation for newly created entries. Fixes #1050 2021-02-10 15:45:41 +01:00
Michael Starke
cc982f2395 Added column to display creation date. Fixed #1150 2021-02-10 14:39:48 +01:00
Michael Starke
fa1094632e Using SFSymbols where possible instead of custom icons 2021-02-03 20:29:57 +01:00
Michael Starke
d0f8c3eafb Added second image store to retrieve SF symbols on supported systems 2021-02-03 19:18:53 +01:00
Michael Starke
51f3d6627f Code style. Removed unused info icon, switched to framework template for sidebar icon 2021-02-03 19:16:17 +01:00
Michael Starke
c50598b8a0 Changed to run only once at 23:00 2021-02-01 20:27:14 +01:00
Michael Starke
e7a5eab982 Created nightly action to migrate from TravisCI 2021-02-01 20:23:31 +01:00
Michael Starke
5e10d3712e Fixed content resizing issues 2021-01-28 20:41:20 +01:00
Michael Starke
04b8e221cb Minor UI change 2021-01-28 13:55:25 +01:00
Michael Starke
059c794b9b Fixed minor autolayout issues on change password window 2021-01-27 18:02:51 +01:00
Michael Starke
0078fae707 Updated german localizations 2021-01-27 17:42:24 +01:00
Michael Starke
76906972f2 Updated to current Xcode. 2021-01-27 17:27:59 +01:00
Michael Starke
98bb204a2f Added missing localizations 2021-01-27 17:27:52 +01:00
Michael Starke
fa08e22cf3 Finished error display in password change sheet 2021-01-27 17:27:45 +01:00
Michael Starke
5457d4dde0 Converted password change window to use NSGridView.
Errors are displayed if a KeePass database is selected as key file.
Password and key errors are now displayed separatly
2021-01-26 21:20:52 +01:00
Dominik Roszkowski
e4fadce3d0 Update Polish translation (#1141) 2021-01-20 13:43:28 +01:00
olieydt
ea9f41bfef Small typo in Localizable.strings (#1134) 2021-01-15 22:30:36 +01:00
Michael Starke
e27526b399 Fix crash when load Argon2id Databases. 2021-01-15 12:58:45 +01:00
Michael Starke
b58d5179a2 Fixed typo in notification varibale 2021-01-13 15:15:23 +01:00
Michael Starke
399cf44d45 Clarified things to do to get async saving to work 2021-01-13 15:12:54 +01:00
Michael Starke
797733130f Fixed regression introduced with e3352efe49 resulting in no password display after reverting a document 2021-01-12 17:36:50 +01:00
Michael Starke
bb3df31d4f Updated localisations. Enabled time slice stepper 2021-01-11 18:18:00 +01:00
Michael Starke
e3b3014084 Updated copyright to 2021 2021-01-11 15:51:40 +01:00
Michael Starke
8496ae20cf Updated sponsors and copyright year 2021-01-11 15:51:24 +01:00
Michael Starke
58399d66be WIP on setup view update 2021-01-11 15:36:43 +01:00
Michael Starke
95da40de44 Explicitly call for isMemberOf to prevent subclasses form being a false-positive 2021-01-11 15:35:54 +01:00
Michael Starke
df7b68b019 Added another update source 2021-01-08 11:57:37 +01:00
Michael Starke
21b0e4c0f2 Minor updates to view update. 2021-01-08 09:08:02 +01:00
Michael Starke
57601798bd Codestyle 2021-01-08 09:07:39 +01:00
Michael Starke
de0319abae Added API to create QR Code images. 2021-01-08 09:07:30 +01:00
Michael Starke
fd88b2c506 Fixed code style. Removed unused code. 2021-01-08 09:06:59 +01:00
Michael Starke
b6df969bf4 TOTPSetup tries to fill itself with values provided by the current entry 2021-01-05 21:32:22 +01:00
Michael Starke
62032cd7d0 Updated to current KeePassKit. Fixed nil assertion when using invalid OTP parameters 2021-01-05 18:12:28 +01:00
Michael Starke
8c017e65c2 Fixed issue resulting in confirmation dialog being displayed if not matches where found. 2021-01-05 15:41:58 +01:00
Michael Starke
15dce5f0b6 Removed fill size window content to fix a lot of toolbar issues 2021-01-05 15:05:22 +01:00
Michael Starke
d22750fefc Intoduced disclosure on QR Code input 2021-01-05 14:35:44 +01:00
Michael Starke
f25db6b418 Fixed regression of newly created entry not being properly selected 2021-01-04 20:49:48 +01:00
Michael Starke
f010ec057d Minor layout changes 2021-01-04 20:49:34 +01:00
Michael Starke
57c3d558f3 Better run-time checks for QRCode scanning 2021-01-04 19:40:08 +01:00
Michael Starke
90093850f9 Use expanded toolbar to accomodate for more room in the title bar. 2021-01-04 16:03:47 +01:00
Michael Starke
6bd6c65dfa Minor improvements for the TOTP setup layout 2020-12-31 21:47:09 +01:00
Michael Starke
ac20664b7a Updated project settings 2020-12-31 21:46:51 +01:00
Michael Starke
7a4d80fd47 OTP setup view controller gets show and parses url strings 2020-12-31 20:23:45 +01:00
Michael Starke
06413b26df Reverted changes for context bar view since the layout was broken 2020-12-30 22:27:13 +01:00
Michael Starke
53ae6dca84 Revert "Added height for context bar"
This reverts commit 4fabee0213.
2020-12-30 22:24:43 +01:00
Michael Starke
4fabee0213 Added height for context bar 2020-12-27 13:40:37 +01:00
Michael Starke
90a0aef2cc Wired up TOTPSetup pop over 2020-12-23 01:33:53 +01:00
Michael Starke
9fe9c6a41d Localized Autotype confirmation. Enhanced layout for window
When confirming, the table view only shows one row, when choosing, at most 5 rows are visible.
2020-12-22 23:42:50 +01:00
Michael Starke
68ccb8e1ad First UI for TOPT setup view 2020-12-21 22:49:27 +01:00
Michael Starke
acd2e1bc0f Fixed missing password colorization 2020-12-21 22:48:57 +01:00
Michael Starke
18e2115119 Updated sponsors 2020-12-20 14:03:22 +01:00
Michael Starke
d466c6d026 Updated localizations. Added edit button to TOTP view 2020-12-18 13:43:14 +01:00
a2y4
a58766146f Add Japanese translation files. (#1100)
* Add Japanese translation files.

* Update translations
2020-12-17 13:09:59 +01:00
Anton Glezman
dc31a81d48 Updated russian localization (#1114) 2020-12-17 13:07:35 +01:00
Andreas Kromke
48491c0712 German localisation improved, one typo in US localisation corrected (#1119)
* Update AutotypeCandidateSelectionView.strings

typos, missing localisation

* Update AutotypeDoctorReportViewController.strings

localisation improved

* Update DatabaseSettingsWindow.strings

localisation improved

* Update EntryInspectorView.strings

localisation improved

* Update GeneralPreferences.strings

localisation improved

* Update GroupInspectorView.strings

unclear if Autotype or Auto-Type, but at least should be consistent

* Update IconSelection.strings

localisation improved

* Update InfoPlist.strings

localisation improved

* Update IntegrationPreferences.strings

localisation improved

* Update Localizable.strings

localisation improved

* Update Localizable.strings

typo

* Update MainMenu.strings

localisation improved

* Update OpenPanelAccessoryView.strings

localised

* Update ReferenceBuilderView.strings

localisation improved

* Update PasswordCreatorView.strings

localisation improved

* Update PluginDataView.strings

localisation improved

* Update MainMenu.strings

localisation improved

* Update Localizable.strings

translations should be consistent

* Update Localizable.strings

consistency

* Update Localizable.strings

consistency

* Update Localizable.strings

consistency

* Update IntegrationPreferences.strings

consistency

* Update GroupInspectorView.strings

consistency

* Update EntryInspectorView.strings

consistency
2020-12-17 13:07:21 +01:00
Michael Starke
b98b5635d5 Use simple counter display instead of progress bar. 2020-12-17 01:52:52 +01:00
Michael Starke
fa85da3f82 Removed custom OTP entry category since KeePassKit now has all we need 2020-12-12 14:00:33 +01:00
Michael Starke
bb73628484 Enabled Time OTP display. 2020-12-11 17:51:09 +01:00
Michael Starke
baaf10d6f3 Added QR code scanner tooling for use in OTP auth URLs 2020-12-10 21:02:22 +01:00
Michael Starke
4caea9080e Correctly scale down image if they are portrait not only landscape 2020-12-02 23:45:59 +01:00
Michael Starke
1e43e608ed Use newest Xcode version on travis 2020-12-02 17:42:36 +01:00
Michael Starke
b04c252a69 Display screenshot of target window in autotype confirmation/selection dialog. 2020-12-02 17:34:17 +01:00
Michael Starke
03c1d5ecee Add setting to always show confirmation before autotype execution 2020-12-02 17:33:40 +01:00
Michael Starke
0f7604ac88 Removed unused key 2020-12-02 17:33:12 +01:00
Michael Starke
784afaee97 Add windowID to info dictionary 2020-12-02 17:33:01 +01:00
Michael Starke
e99f2e2619 Updated to current KeePassKit 2020-12-02 17:32:47 +01:00
Michael Starke
1c76e50192 Adopted KeePassKit attribute keys and stripped our custom ones 2020-12-01 13:38:34 +01:00
Michael Starke
9716bfc8e8 Deleted unused header file 2020-11-30 15:44:36 +01:00
Michael Starke
e08b116aa0 WIP on adding TOTP ui to entry view 2020-11-28 23:10:45 +01:00
Michael Starke
7c9460d027 Converted to class properties and modern obj-c syntax 2020-11-26 12:08:32 +01:00
Michael Starke
3807b0a0b7 Added tooling for OTP handling to KPKEntry 2020-11-26 12:08:17 +01:00
Michael Starke
65626e3b11 Fixed wrong selector in Test 2020-11-25 15:32:42 +01:00
Michael Starke
e2b35c6552 Moved to non-deprecated archiving 2020-11-25 15:32:33 +01:00
Michael Starke
501501fce1 Enable full size content for better big sur experience 2020-11-24 13:37:03 +01:00
Michael Starke
381d4b1cac Updated to current KeePassKit to enable correct builds on Apple Silicon 2020-11-23 13:52:29 +01:00
Michael Starke
c4d7025163 Updated deprecated values 2020-11-12 11:03:23 +01:00
Michael Starke
301ab03266 Moved to NSFilePromiseProvider API for attachment table view 2020-11-09 19:23:28 +01:00
Michael Starke
8407186a38 Removed unused colours. Adjusted blue and orange to be more readable 2020-11-09 18:26:45 +01:00
Michael Starke
c0a64a1bc3 Enabled always verify autotype match settings. UI is missing for this setting 2020-11-04 18:25:32 +01:00
Michael Starke
8e3bca062b Fixed regression in Preferences preventing willShowTab and didShowTab from being called. 2020-11-03 17:08:09 +01:00
Michael Starke
927a4bf86e Updated to Xcode 12.1 2020-11-03 11:38:11 +01:00
Michael Starke
e82e2fe4a2 Revert "Adjusted checks for auto-type permissions"
This reverts commit 7095d55670.

# Conflicts:
#	MacPass/MPAutotypeEnvironment.h
#	MacPass/MPAutotypeEnvironment.m
2020-11-03 11:15:50 +01:00
Michael Starke
499b7fdd6b Updated to public KeePassKit version 2020-10-19 00:02:00 +02:00
Michael Starke
0f2300a981 Added target application icon to candidate selection window 2020-10-12 16:07:45 +02:00
Michael Starke
9d153a4397 Updated to Xcode 12 2020-10-08 23:29:13 +02:00
Michael Starke
2ad4bd2abc correctly set global autotype on initailizer 2020-10-08 23:28:54 +02:00
Michael Starke
bda0a25fe0 Updated to current KeePassKit.
This requires to link and copy KissXML since KeePassKit does not contain it anymore to fix nesting issues with Carthage
2020-09-24 16:59:48 +02:00
Michael Starke
7095d55670 Adjusted checks for auto-type permissions
We do not need to check for screen recording permissions, if auto-type is executed. Only global auto-type requires screen recording permissions and should check for them.
2020-09-21 17:44:15 +02:00
Michael Starke
e4946bd91b Temporary switch to local development branch 2020-09-09 10:44:03 +02:00
Michael Starke
0913aba1cf Updated Xcode checks 2020-09-09 10:44:03 +02:00
Michael Starke
6b10539a3f Use properties. 2020-09-09 10:44:03 +02:00
Michael Starke
c4d9c10cb8 Enabled display of prettified passwords ind password generator and entry inspector 2020-09-09 10:44:03 +02:00
Michael Starke
badd22793d Use automatic row height to allow for multi-line custom fields 2020-09-09 10:44:03 +02:00
Michael Starke
e03660b184 Fixed issue with first entry being displayed in inspector when a group is clicked. 2020-09-09 10:44:03 +02:00
Michael Starke
768f49ab0b Removed unused code 2020-09-09 10:44:03 +02:00
Michael Starke
18c7930dba Use property instead of method 2020-09-09 10:44:03 +02:00
Michael Starke
f626266fa7 Updated to current KeePassKit 2020-09-09 10:44:03 +02:00
Vyacheslav Pukhanov
171d6e4bdc adjusted welcome view layout (#1101) 2020-09-09 10:43:34 +02:00
Hugo Stijns
af65d4029b Update organization in GitHub URL (#1105) 2020-09-09 10:39:16 +02:00
Michael Starke
4e8e9279d3 ordered files by name 2020-07-13 15:46:46 +02:00
Michael Starke
077d5412a4 Fixed typo in comment 2020-07-10 23:48:32 +02:00
Michael Starke
6f1fcad0ca Added override sequence to autotype environment 2020-07-10 16:24:44 +02:00
Michael Starke
c759aeddd9 Changed API for pasteboard to only use a single object. Arrays aren't required. Added concealed/transient type marker to copied items to enhance compatibility with clipboard managers 2020-07-10 15:37:25 +02:00
Michael Starke
641ba2a3fd Updated constraints on preferences views to allow for better transitions between tabs 2020-07-10 12:24:24 +02:00
Michael Starke
be2b5072bf Removed special code for 10.12 and blow since we now target 10.13 and above 2020-07-08 22:11:34 +02:00
Michael Starke
c5694293a5 Removed custom toolbar sizing code since we seem not to need it anymore 2020-07-08 15:38:02 +02:00
Michael Starke
1404f9e336 Removed unneded code for control size settings 2020-07-08 15:22:04 +02:00
Michael Starke
f19fd2e3ac Added sponsor to credits 2020-07-08 15:20:32 +02:00
Thomas
01f7f2baa0 Initial zh-Hant translation (#1065)
* Create AutotypeBuilderView.strings

* Create AutotypeCandidateSelectionView.strings

* Create AutotypeDoctorReportViewController.strings

* Create ContextBar.strings

* Create DatabaseSettingsWindow.strings

* Create DatePickingView.strings

* Create DuplicateEntryOptionsWindow.strings

* Create EntryInspectorView.strings

* Create GeneralPreferences.strings

* Create GroupInspectorView.strings

* Create IconSelection.strings

* Create InfoPlist.strings

* Create InspectorView.strings

* Create IntegrationPreferences.strings

* Create Localizable.strings

* Create Localizable.stringsdict

* Create MainMenu.strings

* Create PasswordCreatorView.strings

* Create PasswordEditWindow.strings

* Create PasswordInputView.strings

* Create PluginDataView.strings

* Create PluginPreferences.strings

* Create PluginRepositoryBrowserView.strings

* Create ReferenceBuilderView.strings

* Create SavePanelAccessoryView.strings

* Create UpdatePreferences.strings

* Create WelcomeView.strings

* Create WorkflowPreferences.strings
2020-07-06 11:35:44 +02:00
Michael Starke
6aef0b198d Removed wrong added attribute since it will interfere with the added custom-values table view 2020-07-01 17:29:18 +02:00
Michael Starke
d00048a7d7 Removed unnecessary constraints from labels and buttons 2020-07-01 15:50:20 +02:00
Michael Starke
4ba40b1d77 Added lost constraint 2020-07-01 15:38:50 +02:00
Michael Starke
58cc929ad9 Using stack view in preparation of hiding empty elements in entry view 2020-07-01 14:34:59 +02:00
Michael Starke
431f9ce22c Fixed broken API contract of returned nil value for non-nil behaviour. Now returning empty dictionary instead 2020-07-01 14:34:29 +02:00
Michael Starke
8f4f3f7053 Use assert to silence compiler warning and remove noise diagnotics pragma 2020-07-01 14:33:27 +02:00
Michael Starke
fe7c647bcf Added custom MPTabViewController to resize window to tab sizes on change 2020-06-30 23:49:06 +02:00
Michael Starke
208c3e6c31 Moved to using NSTabViewController for preferences instead of rolling our own implementation 2020-06-30 13:59:54 +02:00
Modo Ltunzher
da795b52de Ukrainian translations (#1076)
* Ukrainian translations

* Typo fixes. Kudos to @troyane

* Fix typo in DEFAULT_GROUP_NAME

* Fix typos

Applied fixes in Localizable.strings, MainMenu.strings, PasswordCreatorView.strings, PluginPreferences.strings.

Co-authored-by: Nazar Gerasymchuk <troyan3@gmail.com>
2020-05-20 13:40:38 +02:00
Alex Rakov
c4fe593e8f Use DuckDuckGo favicon service (#1073)
* Use DuckDuckGo favicon service

There are multiple ways of how favicon of a website can be published:
- Have a `favicon.ico` file under the website root
- Set through `<link rel="shortcut icon" href="..." />` tag
- Set through `<link rel="icon" href="..." />` tag, or
- Set through platform-specific tags like `<link rel="apple-touch-icon" href="..." />`

Current implementation only supports first option, which does not work in many cases.

Instead of implementing favicon fetching logic from scratch, favicon fetching services can be used.
There are multiple of them, e.g.:
- https://icons.duckduckgo.com/ip3/www.google.com.ico
- https://www.google.com/s2/favicons?domain=www.google.com

This change switched from fetching favicon from the original host to DuckDuckGo.

* Create UX for favicon download method preferences

* Add preferences for favicon download method

* Adjust preferences window location

Also, sort localized resources

Co-authored-by: Alex Rakov <alexander-rakov@users.noreply.github.com>
2020-05-15 19:37:52 +02:00
Michael Starke
67eee29fdf Fixed regression that resulted in firstResponders not getting correctly updated on view changes 2020-05-12 14:13:04 +02:00
Michael Starke
0617b0e601 Update to newer file version 2020-05-12 14:13:04 +02:00
Michael Starke
85ba893724 Clarified commented code 2020-05-12 14:13:04 +02:00
Gilles Debunne
96f6b157c7 Fix typo (#1071) 2020-05-12 13:59:36 +02:00
Michael Starke
2d7a01df10 Merge branch 'release/0.7.12' 2020-03-25 21:48:07 +01:00
Michael Starke
0df8eba2b6 Tags are now search case insensitive (fixes #1048)
The issue was that the tags string array was not correctly searched case insensitive via the predicate CONTAINS
2020-03-20 17:24:33 +01:00
Michael Starke
16ca18623e Removed double function calls 2020-03-20 17:05:37 +01:00
Michael Starke
417540d272 Added Focus Proxy as skippable window title 2020-03-20 17:05:37 +01:00
Michael Starke
7b2b17e42a Filter window titles and skip wellknown false positives 2020-03-20 17:05:37 +01:00
Michael Starke
e63ea8c110 Fixed low contrast in Autotype candidate selection window (fixes #1054) 2020-03-20 00:08:12 +01:00
Michael Starke
afc0e637f1 Merge branch 'hotfix/fix-missing-key-selection-in-change-password-dialog'
# Conflicts:
#	MacPass.xcodeproj/project.pbxproj
2020-03-20 00:07:10 +01:00
Chester Liu
ee7d1df3c3 Update zh-Hans localization (#1058) 2020-03-19 12:44:52 +01:00
Michael Starke
0662a729a0 Merge branch 'feature/nssplitview_to_nssplitviewcontroller' 2020-03-11 07:24:39 +01:00
Benjamin Blonde
c5d5b6c787 Update french localizations (#1047)
- Add 121 missing translations
- Tweak few old translations

Co-authored-by: Michael Starke <michael.starke@hicknhack-software.com>
2020-03-11 07:15:13 +01:00
Bartłomiej Jakub Kwiatek
406cb0f6c0 Updated polish localization (#1042)
Co-authored-by: Bartlomiej.Kwiatek <bartlomiej.kwiatek@vml.com>
2020-03-11 07:13:41 +01:00
Michael Starke
e6cb17caf6 Removed unnecessary identifier 2020-02-05 11:47:11 +01:00
Michael Starke
c277d3f001 Fixed NSSplitView not restoring its state by moving to viewWillLayout 2020-02-05 11:44:52 +01:00
Michael Starke
d6c8674d7b retain window size when content view does change 2020-02-04 23:15:57 +01:00
Michael Starke
d946e80e65 Fixed deprecation warnings 2020-02-03 18:07:38 +01:00
Michael Starke
55fca262ef Fixed more deprecations 2020-02-03 18:06:21 +01:00
Michael Starke
2f42e1498c Updated submodule to fix deprecation warnings 2020-02-03 17:53:21 +01:00
Michael Starke
0e5caab72a Fixed deprecation warnings 2020-02-03 17:51:59 +01:00
Michael Starke
e3352efe49 Using NSSplitViewController for main split view. 2020-01-31 16:30:13 +01:00
242 changed files with 10245 additions and 2365 deletions

32
.github/workflows/nightly.yml vendored Normal file
View File

@@ -0,0 +1,32 @@
name: Nightly
on:
#push:
# branches: [ master ]
#pull_request:
# branches: [ master ]
schedule:
- cron: '0 23 * * *'
workflow_dispatch:
jobs:
nightly:
runs-on: macos-10.15
steps:
- uses: actions/checkout@v2
with:
submodules: recursive
- name: Bootstrap Carthage
run: carthage bootstrap --platform macOS
- name: Install xcpretty
run: gem install xcpretty --no-document --quiet
- name: Build
run: |
set -o pipefail
xcodebuild clean
xcodebuild build -configuration release -project MacPass.xcodeproj -scheme MacPass CODE_SIGNING_REQUIRED=NO -derivedDataPath ./build | xcpretty -c

View File

@@ -1,4 +1,4 @@
osx_image: xcode10.2
osx_image: xcode12.2
xcode_project: MacPass.xcodeproj
xcode_scheme: MacPass
language: objective-c

View File

@@ -1,4 +1,4 @@
github "sparkle-project/Sparkle" ~> 1.22
github "MacPass/TransformerKit" "b28de3a7de9249dd886979cae4985092523b6dd1"
github "MacPass/KeePassKit" ~> 2.4
github "mstarke/HNHUi" ~> 3.0
github "mattt/TransformerKit" ~> 1.1.1
github "MacPass/KeePassKit" "76e6ecda942f9e328efde7883ad75aed7290b632"
github "mstarke/HNHUi" ~> 4.0

View File

@@ -1,5 +1,5 @@
github "MacPass/KeePassKit" "2.4.7"
github "MacPass/TransformerKit" "b28de3a7de9249dd886979cae4985092523b6dd1"
github "mstarke/HNHUi" "3.0"
github "robbiehanson/KissXML" "5.3.1"
github "sparkle-project/Sparkle" "1.22.0"
github "MacPass/KeePassKit" "76e6ecda942f9e328efde7883ad75aed7290b632"
github "mattt/TransformerKit" "1.1.1"
github "mstarke/HNHUi" "4.0.3"
github "robbiehanson/KissXML" "5.3.3"
github "sparkle-project/Sparkle" "1.24.0"

View File

@@ -1,7 +1,7 @@
MacPass, a KeePass compatible Password Manager for OS X
Copyright (C) 2012-2016 Michael Starke, and all MacPass contributors
A full list of contributors can be found at
<https://github.com/mstarke/MacPass/graphs/contributors>
<https://github.com/MacPass/MacPass/graphs/contributors>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1130"
LastUpgradeVersion = "1240"
version = "2.0">
<BuildAction
parallelizeBuildables = "YES"

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="12120" systemVersion="16F73" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17506" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="12120"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17506"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@@ -19,7 +19,7 @@
<rect key="frame" x="0.0" y="0.0" width="392" height="210"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<tokenField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Jzn-UC-Ok8">
<tokenField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Jzn-UC-Ok8">
<rect key="frame" x="20" y="50" width="352" height="66"/>
<constraints>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="66" id="7rr-fC-NeH"/>
@@ -31,13 +31,13 @@
</tokenFieldCell>
</tokenField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="lS4-1R-Bhp">
<rect key="frame" x="215" y="18" width="157" height="25"/>
<rect key="frame" x="215" y="19" width="157" height="23"/>
<buttonCell key="cell" type="roundTextured" title="Set Autotype Sequence" bezelStyle="texturedRounded" alignment="center" lineBreakMode="truncatingTail" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="aOD-Ih-Sft">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="NO" translatesAutoresizingMaskIntoConstraints="NO" id="7xF-eN-vs3">
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="7xF-eN-vs3">
<rect key="frame" x="18" y="176" width="207" height="14"/>
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Available Commands and Placeholders" id="lug-97-H9D">
<font key="font" metaFont="smallSystem"/>
@@ -45,7 +45,7 @@
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9Kw-lW-ASe">
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="9Kw-lW-ASe">
<rect key="frame" x="18" y="124" width="107" height="14"/>
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Autotype Sequence" id="8ny-Qk-Jvo">
<font key="font" metaFont="smallSystem"/>
@@ -53,7 +53,7 @@
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<tokenField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="NO" translatesAutoresizingMaskIntoConstraints="NO" id="k06-gn-ahB">
<tokenField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="k06-gn-ahB">
<rect key="frame" x="20" y="146" width="352" height="22"/>
<constraints>
<constraint firstAttribute="width" relation="lessThanOrEqual" constant="400" id="can-wk-8oX"/>

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="15705" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17506" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15705"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17506"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@@ -11,30 +11,85 @@
<outlet property="contextTableView" destination="Ih2-lo-t2W" id="8uy-Mz-1vc"/>
<outlet property="messageTextField" destination="kDw-2l-7gQ" id="7bW-as-yGU"/>
<outlet property="selectAutotypeContextButton" destination="V5B-Qq-GN8" id="mqv-H3-N01"/>
<outlet property="targetApplicationImageView" destination="bWJ-Ub-c10" id="vTC-FO-QQO"/>
<outlet property="view" destination="Hz6-mo-xeY" id="0bl-1N-x8E"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="Hz6-mo-xeY">
<rect key="frame" x="0.0" y="0.0" width="480" height="241"/>
<rect key="frame" x="0.0" y="0.0" width="480" height="201"/>
<subviews>
<scrollView wantsLayer="YES" autohidesScrollers="YES" horizontalLineScroll="38" horizontalPageScroll="10" verticalLineScroll="38" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="7cB-re-3ys">
<rect key="frame" x="20" y="61" width="440" height="120"/>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="zBX-HB-tR7">
<rect key="frame" x="236" y="13" width="82" height="32"/>
<buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="60p-7v-Nje">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<string key="keyEquivalent" base64-UTF8="YES">
Gw
</string>
</buttonCell>
<connections>
<action selector="cancelSelection:" target="-1" id="EzT-DQ-zhY"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="V5B-Qq-GN8">
<rect key="frame" x="318" y="13" width="148" height="32"/>
<buttonCell key="cell" type="push" title="Perform Autotype" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="w7H-hx-CUF">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<string key="keyEquivalent" base64-UTF8="YES">
DQ
</string>
</buttonCell>
<connections>
<action selector="selectAutotypeContext:" target="-2" id="a2F-ID-uOd"/>
</connections>
</button>
<stackView distribution="fill" orientation="vertical" alignment="centerX" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="82Y-g7-4wV">
<rect key="frame" x="20" y="109" width="440" height="72"/>
<subviews>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="bWJ-Ub-c10">
<rect key="frame" x="204" y="40" width="32" height="32"/>
<constraints>
<constraint firstAttribute="height" relation="lessThanOrEqual" constant="128" id="Rzo-8n-W92"/>
<constraint firstAttribute="width" relation="lessThanOrEqual" constant="128" id="uhc-Ce-lb8"/>
</constraints>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyUpOrDown" image="NSApplicationIcon" id="d6x-JH-Lw2"/>
</imageView>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="kDw-2l-7gQ">
<rect key="frame" x="-2" y="0.0" width="444" height="32"/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" title="There are multiple matches for the current window. Please select which match should be used." id="gcf-gb-ZsF">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<visibilityPriorities>
<integer value="1000"/>
<integer value="1000"/>
</visibilityPriorities>
<customSpacing>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
</customSpacing>
</stackView>
<scrollView wantsLayer="YES" verticalCompressionResistancePriority="250" autohidesScrollers="YES" horizontalLineScroll="38" horizontalPageScroll="10" verticalLineScroll="38" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="7cB-re-3ys">
<rect key="frame" x="20" y="61" width="440" height="40"/>
<clipView key="contentView" id="WSc-o2-GsZ">
<rect key="frame" x="1" y="1" width="438" height="118"/>
<rect key="frame" x="1" y="1" width="438" height="38"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView verticalHuggingPriority="750" ambiguous="YES" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" alternatingRowBackgroundColors="YES" columnReordering="NO" multipleSelection="NO" emptySelection="NO" autosaveColumns="NO" typeSelect="NO" rowHeight="36" viewBased="YES" id="Ih2-lo-t2W">
<rect key="frame" x="0.0" y="0.0" width="438" height="118"/>
<autoresizingMask key="autoresizingMask"/>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" alternatingRowBackgroundColors="YES" columnReordering="NO" multipleSelection="NO" emptySelection="NO" autosaveColumns="NO" typeSelect="NO" rowHeight="36" viewBased="YES" id="Ih2-lo-t2W">
<rect key="frame" x="0.0" y="0.0" width="438" height="38"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
<tableColumns>
<tableColumn width="435" minWidth="40" maxWidth="1000" id="wTy-0L-yzY">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
</tableHeaderCell>
@@ -45,8 +100,8 @@
</textFieldCell>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES"/>
<prototypeCellViews>
<tableCellView misplaced="YES" id="vkI-FK-7wg" customClass="MPExtendedTableCellView">
<rect key="frame" x="1" y="1" width="435" height="17"/>
<tableCellView id="vkI-FK-7wg" customClass="MPExtendedTableCellView">
<rect key="frame" x="1" y="1" width="435" height="36"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Utl-Gl-ETE">
@@ -111,59 +166,26 @@
<autoresizingMask key="autoresizingMask"/>
</scroller>
</scrollView>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" preferredMaxLayoutWidth="330" translatesAutoresizingMaskIntoConstraints="NO" id="kDw-2l-7gQ">
<rect key="frame" x="18" y="189" width="444" height="32"/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" title="There are multiple matches for the current window. Please select which match should be used." id="gcf-gb-ZsF">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="zBX-HB-tR7">
<rect key="frame" x="236" y="13" width="82" height="32"/>
<buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="60p-7v-Nje">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<string key="keyEquivalent" base64-UTF8="YES">
Gw
</string>
</buttonCell>
<connections>
<action selector="cancelSelection:" target="-1" id="EzT-DQ-zhY"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="V5B-Qq-GN8">
<rect key="frame" x="318" y="13" width="148" height="32"/>
<buttonCell key="cell" type="push" title="Perform Autotype" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="w7H-hx-CUF">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<string key="keyEquivalent" base64-UTF8="YES">
DQ
</string>
</buttonCell>
<connections>
<action selector="selectAutotypeContext:" target="-2" id="a2F-ID-uOd"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstAttribute="bottom" secondItem="V5B-Qq-GN8" secondAttribute="bottom" constant="20" id="FMz-e1-hOB"/>
<constraint firstItem="kDw-2l-7gQ" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" symbolic="YES" id="GcO-tk-i2z"/>
<constraint firstItem="kDw-2l-7gQ" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" constant="20" symbolic="YES" id="OHm-6j-uPs"/>
<constraint firstAttribute="trailing" secondItem="82Y-g7-4wV" secondAttribute="trailing" constant="20" symbolic="YES" id="Fvf-rw-waQ"/>
<constraint firstAttribute="trailing" secondItem="V5B-Qq-GN8" secondAttribute="trailing" constant="20" symbolic="YES" id="SRs-hx-av7"/>
<constraint firstItem="V5B-Qq-GN8" firstAttribute="leading" secondItem="zBX-HB-tR7" secondAttribute="trailing" constant="12" symbolic="YES" id="UuF-Ba-HS5"/>
<constraint firstItem="zBX-HB-tR7" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" symbolic="YES" id="ZNu-po-1u8"/>
<constraint firstItem="7cB-re-3ys" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" symbolic="YES" id="egY-ml-urP"/>
<constraint firstItem="7cB-re-3ys" firstAttribute="top" secondItem="82Y-g7-4wV" secondAttribute="bottom" constant="8" symbolic="YES" id="f0g-kf-N2j"/>
<constraint firstItem="82Y-g7-4wV" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" constant="20" symbolic="YES" id="hDi-Va-2Mb"/>
<constraint firstAttribute="trailing" secondItem="7cB-re-3ys" secondAttribute="trailing" constant="20" symbolic="YES" id="hqW-Hz-bFN"/>
<constraint firstItem="V5B-Qq-GN8" firstAttribute="baseline" secondItem="zBX-HB-tR7" secondAttribute="baseline" id="iAg-1w-h25"/>
<constraint firstItem="zBX-HB-tR7" firstAttribute="top" secondItem="7cB-re-3ys" secondAttribute="bottom" constant="20" symbolic="YES" id="onA-YV-ezJ"/>
<constraint firstItem="7cB-re-3ys" firstAttribute="top" secondItem="kDw-2l-7gQ" secondAttribute="bottom" constant="8" symbolic="YES" id="ss6-Ku-XPY"/>
<constraint firstAttribute="trailing" secondItem="kDw-2l-7gQ" secondAttribute="trailing" constant="20" symbolic="YES" id="zSz-fH-fVn"/>
<constraint firstItem="82Y-g7-4wV" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" symbolic="YES" id="uoN-Et-pWh"/>
</constraints>
<point key="canvasLocation" x="176" y="-39.5"/>
<point key="canvasLocation" x="-388" y="-2744"/>
</customView>
</objects>
<resources>
<image name="NSActionTemplate" width="14" height="14"/>
<image name="NSApplicationIcon" width="32" height="32"/>
</resources>
</document>

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="15702" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17156" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15702"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17156"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@@ -140,7 +140,7 @@
<constraint firstItem="d5Z-hD-bpr" firstAttribute="leading" secondItem="6vq-iM-inn" secondAttribute="leading" id="oZ8-mG-RYJ"/>
<constraint firstAttribute="trailing" secondItem="BHb-cd-Q0r" secondAttribute="trailing" constant="20" symbolic="YES" id="ryW-3O-g6b"/>
</constraints>
<point key="canvasLocation" x="-409" y="-112.5"/>
<point key="canvasLocation" x="-742" y="-147"/>
</customView>
</objects>
<resources>

View File

@@ -1,6 +1,6 @@
{\rtf1\ansi\ansicpg1252\cocoartf1671\cocoasubrtf600
{\fonttbl\f0\fswiss\fcharset0 Helvetica-Bold;\f1\fswiss\fcharset0 Helvetica;\f2\fnil\fcharset0 SFProText-Regular;
}
{\rtf1\ansi\ansicpg1252\cocoartf2513
\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fswiss\fcharset0 Helvetica-Bold;\f1\fswiss\fcharset0 Helvetica;\f2\fnil\fcharset0 HelveticaNeue;
\f3\fnil\fcharset0 AppleColorEmoji;\f4\fnil\fcharset0 SFProText-Regular;}
{\colortbl;\red255\green255\blue255;\red0\green0\blue0;\red9\green79\blue209;\red69\green60\blue204;
\red52\green110\blue183;\red38\green38\blue38;}
{\*\expandedcolortbl;;\cssrgb\c0\c0\c0\cname textColor;\cssrgb\c0\c40784\c85490\cname linkColor;\cssrgb\c34510\c33725\c83922;
@@ -14,7 +14,7 @@
\f1\b0 \cf2 macpassapp.org}}
\f1\b0 \cf3 \
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\partightenfactor0
{\field{\*\fldinst{HYPERLINK "https://github.com/mstarke/MacPass"}}{\fldrslt \cf3 MacPass}} \cf2 on GitHub.\
{\field{\*\fldinst{HYPERLINK "https://github.com/MacPass/MacPass"}}{\fldrslt \cf3 MacPass}} \cf2 on GitHub.\
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\partightenfactor0
\f0\b \cf2 \
@@ -22,7 +22,7 @@ License:\
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\partightenfactor0
\f1\b0 \cf2 MacPass KeePass compatible client for OS X\
Copyright (c) 2012-2020 Michael Starke, HicknHack Software GmbH\
Copyright (c) 2012-2021 Michael Starke, HicknHack Software GmbH\
\
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by\
the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\
@@ -37,12 +37,33 @@ You should have received a copy of the GNU General Public License along with thi
\
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\partightenfactor0
\f0\b \cf0 \kerning1\expnd0\expndtw0 Sponsors:
\f2\b0\fs52 \
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0
{\field{\*\fldinst{HYPERLINK "mailto:frank.mittelbach@latex-project.org"}}{\fldrslt
\f1\fs24 \cf0 \kerning1\expnd0\expndtw3
Frank Mittelbach}}
\f1\fs24 \kerning1\expnd0\expndtw3
\
\pard\pardeftab720\partightenfactor0
{\field{\*\fldinst{HYPERLINK "mailto:github@soebes.com"}}{\fldrslt \cf0 \kerning1\expnd0\expndtw3
Karl Heinz Marbaise}}\kerning1\expnd0\expndtw3
\f3 \kerning1\expnd0\expndtw3
\uc0\u55356 \u57225
\f1 \kerning1\expnd0\expndtw3
\
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0
\cf0 \kerning1\expnd0\expndtw3
\
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\partightenfactor0
\f0\b \cf2 \kerning1\expnd0\expndtw0 Credits:\
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\partightenfactor0
\f1\b0 \cf2 \
Dutch translation: {\field{\*\fldinst{HYPERLINK "https://github.com/FrankKooij"}}{\fldrslt \cf3 Frank Kooij}},
\f2 \cf4 \expnd0\expndtw0\kerning0
\f4 \cf4 \expnd0\expndtw0\kerning0
{\field{\*\fldinst{HYPERLINK "https://github.com/clone1612"}}{\fldrslt
\f1 \cf3 \kerning1\expnd0\expndtw0 Jannick Hemelhof}}
\f1 \cf0 \kerning1\expnd0\expndtw0 \

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17701"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@@ -52,12 +52,12 @@
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="196" y="240" width="500" height="360"/>
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
<view key="contentView" id="2">
<rect key="frame" x="0.0" y="0.0" width="553" height="484"/>
<view key="contentView" misplaced="YES" id="2">
<rect key="frame" x="0.0" y="0.0" width="500" height="360"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="288">
<rect key="frame" x="480" y="13" width="59" height="32"/>
<rect key="frame" x="385" y="13" width="59" height="32"/>
<buttonCell key="cell" type="push" title="OK" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="289">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
@@ -70,7 +70,7 @@ DQ
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="956">
<rect key="frame" x="398" y="13" width="82" height="32"/>
<rect key="frame" x="303" y="13" width="82" height="32"/>
<buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="957">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
@@ -83,16 +83,16 @@ Gw
</connections>
</button>
<tabView translatesAutoresizingMaskIntoConstraints="NO" id="357">
<rect key="frame" x="13" y="41" width="527" height="437"/>
<rect key="frame" x="13" y="41" width="432" height="338"/>
<font key="font" metaFont="system"/>
<tabViewItems>
<tabViewItem label="General" identifier="1" id="358">
<view key="view" id="361">
<rect key="frame" x="10" y="33" width="454" height="267"/>
<rect key="frame" x="10" y="33" width="454" height="265"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="231">
<rect key="frame" x="154" y="225" width="280" height="22"/>
<rect key="frame" x="154" y="224" width="280" height="21"/>
<constraints>
<constraint firstAttribute="width" constant="280" id="cra-uC-nCv"/>
</constraints>
@@ -103,7 +103,7 @@ Gw
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="256">
<rect key="frame" x="70" y="201" width="78" height="17"/>
<rect key="frame" x="70" y="201" width="78" height="16"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Description:" id="257">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@@ -111,7 +111,7 @@ Gw
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="189">
<rect key="frame" x="46" y="229" width="102" height="17"/>
<rect key="frame" x="46" y="228" width="102" height="16"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Database name:" id="190">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@@ -119,7 +119,7 @@ Gw
</textFieldCell>
</textField>
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="1394">
<rect key="frame" x="152" y="73" width="71" height="25"/>
<rect key="frame" x="152" y="72" width="71" height="25"/>
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="1395">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="menu"/>
@@ -132,7 +132,7 @@ Gw
</popUpButtonCell>
</popUpButton>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="1404">
<rect key="frame" x="60" y="78" width="88" height="17"/>
<rect key="frame" x="60" y="78" width="88" height="16"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Compression:" id="1405">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@@ -140,7 +140,7 @@ Gw
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="1434">
<rect key="frame" x="107" y="48" width="41" height="17"/>
<rect key="frame" x="107" y="48" width="41" height="16"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Color:" id="1435">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@@ -148,7 +148,7 @@ Gw
</textFieldCell>
</textField>
<colorWell translatesAutoresizingMaskIntoConstraints="NO" id="1439" customClass="HNHUIColorWell">
<rect key="frame" x="154" y="45" width="44" height="23"/>
<rect key="frame" x="154" y="44" width="44" height="23"/>
<constraints>
<constraint firstAttribute="width" constant="44" id="XBF-V3-71G"/>
<constraint firstAttribute="height" constant="23" id="fgN-h5-Mr8"/>
@@ -156,10 +156,10 @@ Gw
<color key="color" red="0.05813049898" green="0.055541899059999997" blue="1" alpha="1" colorSpace="calibratedRGB"/>
</colorWell>
<scrollView horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="1530">
<rect key="frame" x="154" y="117" width="280" height="100"/>
<rect key="frame" x="154" y="116" width="280" height="100"/>
<clipView key="contentView" drawsBackground="NO" id="WOI-1v-RCe">
<rect key="frame" x="1" y="1" width="278" height="98"/>
<autoresizingMask key="autoresizingMask"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textView importsGraphics="NO" verticallyResizable="YES" usesFontPanel="YES" findStyle="panel" continuousSpellChecking="YES" allowsUndo="YES" usesRuler="YES" allowsNonContiguousLayout="YES" spellingCorrection="YES" smartInsertDelete="YES" id="1531">
<rect key="frame" x="0.0" y="0.0" width="278" height="98"/>
@@ -186,7 +186,7 @@ Gw
</scroller>
</scrollView>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="RhU-5I-S5l">
<rect key="frame" x="75" y="20" width="73" height="17"/>
<rect key="frame" x="75" y="20" width="73" height="16"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="File format:" id="bTk-YZ-x0G">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@@ -194,7 +194,7 @@ Gw
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="1Ci-0B-yV5">
<rect key="frame" x="152" y="20" width="72" height="17"/>
<rect key="frame" x="152" y="20" width="72" height="16"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="VersionInfo" id="Ush-4r-A1A">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@@ -236,11 +236,11 @@ Gw
</tabViewItem>
<tabViewItem label="Security" identifier="" id="370">
<view key="view" id="371">
<rect key="frame" x="10" y="33" width="454" height="243"/>
<rect key="frame" x="10" y="33" width="412" height="292"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="3ek-Rg-w82">
<rect key="frame" x="150" y="199" width="155" height="25"/>
<rect key="frame" x="129" y="248" width="155" height="25"/>
<constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="150" id="F8Y-Uw-4mL"/>
</constraints>
@@ -251,7 +251,7 @@ Gw
</popUpButtonCell>
</popUpButton>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="vH7-5a-52C">
<rect key="frame" x="73" y="205" width="73" height="17"/>
<rect key="frame" x="52" y="255" width="73" height="16"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Encryption:" id="gxY-UL-bEG">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@@ -259,29 +259,29 @@ Gw
</textFieldCell>
</textField>
<box title="Key derivation" translatesAutoresizingMaskIntoConstraints="NO" id="pbl-Mb-r8V">
<rect key="frame" x="17" y="16" width="420" height="178"/>
<rect key="frame" x="17" y="16" width="378" height="227"/>
<view key="contentView" id="hkT-SX-Te1">
<rect key="frame" x="3" y="3" width="414" height="160"/>
<rect key="frame" x="3" y="3" width="372" height="209"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="P98-Cu-Tha">
<rect key="frame" x="251" y="18" width="143" height="23"/>
<rect key="frame" x="209" y="18" width="143" height="23"/>
<buttonCell key="cell" type="roundTextured" title="Generate Parameters" bezelStyle="texturedRounded" alignment="center" lineBreakMode="truncatingTail" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="PoI-Er-Y8P">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
</button>
<tabView drawsBackground="NO" type="noTabsNoBorder" translatesAutoresizingMaskIntoConstraints="NO" id="2MY-PW-kzL">
<rect key="frame" x="12" y="49" width="390" height="62"/>
<rect key="frame" x="12" y="49" width="348" height="111"/>
<font key="font" metaFont="system"/>
<tabViewItems>
<tabViewItem label="Aes" identifier="1" id="ft1-pl-lpO">
<view key="view" id="88i-IZ-Yev">
<rect key="frame" x="0.0" y="0.0" width="390" height="62"/>
<rect key="frame" x="0.0" y="0.0" width="390" height="61"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ztz-iY-hWV">
<rect key="frame" x="64" y="23" width="50" height="17"/>
<rect key="frame" x="64" y="23" width="50" height="16"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Rounds" id="uUQ-9s-M5E">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@@ -289,7 +289,7 @@ Gw
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="8aq-34-rcd">
<rect key="frame" x="120" y="20" width="150" height="22"/>
<rect key="frame" x="120" y="20" width="150" height="21"/>
<constraints>
<constraint firstAttribute="width" constant="150" id="cdb-ED-zB3"/>
</constraints>
@@ -314,13 +314,13 @@ Gw
</constraints>
</view>
</tabViewItem>
<tabViewItem label="Argon2" identifier="2" id="6qB-sH-9FI">
<tabViewItem label="Argon2d" identifier="2" id="6qB-sH-9FI">
<view key="view" id="ORc-Gq-vFd">
<rect key="frame" x="0.0" y="0.0" width="348" height="114"/>
<rect key="frame" x="0.0" y="0.0" width="348" height="111"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="751" translatesAutoresizingMaskIntoConstraints="NO" id="aNy-eF-jKq">
<rect key="frame" x="39" y="87" width="54" height="17"/>
<rect key="frame" x="39" y="85" width="54" height="16"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Threads" id="2QI-ne-N5d">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@@ -328,7 +328,7 @@ Gw
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="751" translatesAutoresizingMaskIntoConstraints="NO" id="ml2-wP-EaZ">
<rect key="frame" x="32" y="55" width="61" height="17"/>
<rect key="frame" x="32" y="54" width="61" height="16"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Iterations" id="2ZA-Gc-JdZ">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@@ -336,7 +336,7 @@ Gw
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="178-0f-guB">
<rect key="frame" x="99" y="84" width="150" height="22"/>
<rect key="frame" x="99" y="82" width="150" height="21"/>
<constraints>
<constraint firstAttribute="width" constant="150" id="IEL-Dn-XFa"/>
</constraints>
@@ -351,7 +351,7 @@ Gw
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="39N-8Q-J8b">
<rect key="frame" x="99" y="52" width="150" height="22"/>
<rect key="frame" x="99" y="51" width="150" height="21"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="9wr-x8-Wtv">
<numberFormatter key="formatter" formatterBehavior="default10_4" usesGroupingSeparator="NO" groupingSize="0" minimumIntegerDigits="0" maximumIntegerDigits="42" id="Kim-cZ-JbF">
<real key="minimum" value="1"/>
@@ -363,7 +363,7 @@ Gw
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="eEW-oa-V7U">
<rect key="frame" x="99" y="20" width="129" height="22"/>
<rect key="frame" x="99" y="20" width="129" height="21"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="M1E-89-YVm">
<byteCountFormatter key="formatter" countStyle="binary" allowsNonnumericFormatting="NO" id="tSh-D8-DnC"/>
<font key="font" metaFont="system"/>
@@ -372,7 +372,7 @@ Gw
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="751" translatesAutoresizingMaskIntoConstraints="NO" id="9kV-19-lm6">
<rect key="frame" x="39" y="23" width="54" height="17"/>
<rect key="frame" x="39" y="23" width="54" height="16"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Memory" id="iRY-If-Kwn">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@@ -380,7 +380,7 @@ Gw
</textFieldCell>
</textField>
<stepper horizontalHuggingPriority="750" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="NfL-iP-SRk">
<rect key="frame" x="233" y="18" width="19" height="27"/>
<rect key="frame" x="233" y="17" width="19" height="28"/>
<stepperCell key="cell" continuous="YES" alignment="left" maxValue="100" id="dvB-J3-Wmb"/>
</stepper>
</subviews>
@@ -411,10 +411,16 @@ Gw
</constraints>
</view>
</tabViewItem>
<tabViewItem label="Argon2id" identifier="" id="xI9-6m-9ju">
<view key="view" id="k6k-0V-j7w">
<rect key="frame" x="0.0" y="0.0" width="348" height="111"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
</view>
</tabViewItem>
</tabViewItems>
</tabView>
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="2cq-R3-Ksh">
<rect key="frame" x="130" y="116" width="155" height="25"/>
<rect key="frame" x="109" y="165" width="155" height="25"/>
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="Pb9-YV-rYe">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="menu"/>
@@ -425,7 +431,7 @@ Gw
</connections>
</popUpButton>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="4el-r1-iRL">
<rect key="frame" x="63" y="122" width="63" height="17"/>
<rect key="frame" x="42" y="172" width="63" height="16"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Algorithm" id="GVd-KH-pHc">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14460.31"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17701"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@@ -19,6 +19,7 @@
<outlet property="customFieldsTableView" destination="193" id="266"/>
<outlet property="enableAutotypeCheckButton" destination="kdV-Xa-8p3" id="vlC-HP-lBv"/>
<outlet property="expiresCheckButton" destination="7" id="286"/>
<outlet property="fieldsStackView" destination="dx3-E2-FFt" id="GbY-9q-iEy"/>
<outlet property="generalView" destination="4" id="270"/>
<outlet property="generatePasswordButton" destination="59" id="282"/>
<outlet property="infoTabControl" destination="82" id="264"/>
@@ -46,8 +47,8 @@
<rect key="frame" x="0.0" y="0.0" width="293" height="493"/>
<subviews>
<segmentedControl verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="82">
<rect key="frame" x="57" y="469" width="179" height="19"/>
<segmentedCell key="cell" controlSize="small" borderStyle="border" alignment="left" style="texturedSquare" trackingMode="selectOne" id="238">
<rect key="frame" x="76" y="470" width="142" height="19"/>
<segmentedCell key="cell" controlSize="small" borderStyle="border" alignment="left" style="capsule" trackingMode="selectOne" id="238">
<font key="font" metaFont="smallSystem"/>
<segments>
<segment label="General" selected="YES"/>
@@ -96,18 +97,17 @@
<rect key="frame" x="20" y="26" width="253" height="396"/>
<clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="F3N-QI-Di5">
<rect key="frame" x="1" y="1" width="251" height="394"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" multipleSelection="NO" autosaveColumns="NO" rowHeight="36" rowSizeStyle="automatic" viewBased="YES" id="137">
<rect key="frame" x="0.0" y="0.0" width="251" height="394"/>
<autoresizingMask key="autoresizingMask"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" name="alternateSelectedControlTextColor" catalog="System" colorSpace="catalog"/>
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
<tableColumns>
<tableColumn width="248" minWidth="40" maxWidth="1000" id="140">
<tableColumn width="219" minWidth="40" maxWidth="1000" id="140">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" white="0.33333298560000002" alpha="1" colorSpace="calibratedWhite"/>
</tableHeaderCell>
@@ -119,11 +119,11 @@
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
<prototypeCellViews>
<tableCellView identifier="NormalCell" id="143">
<rect key="frame" x="1" y="1" width="248" height="36"/>
<rect key="frame" x="11" y="1" width="228" height="36"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView translatesAutoresizingMaskIntoConstraints="NO" id="144">
<rect key="frame" x="3" y="2" width="32" height="32"/>
<rect key="frame" x="3" y="-1" width="32" height="38"/>
<constraints>
<constraint firstAttribute="width" constant="32" id="153"/>
<constraint firstAttribute="height" constant="32" id="154"/>
@@ -131,7 +131,7 @@
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="NSActionTemplate" id="152"/>
</imageView>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="145">
<rect key="frame" x="41" y="10" width="206" height="17"/>
<rect key="frame" x="41" y="10" width="186" height="16"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="151">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@@ -152,11 +152,11 @@
</connections>
</tableCellView>
<tableCellView identifier="SelectedCell" id="141" customClass="MPSelectedAttachmentTableCellView">
<rect key="frame" x="1" y="39" width="248" height="36"/>
<rect key="frame" x="11" y="39" width="228" height="36"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView translatesAutoresizingMaskIntoConstraints="NO" id="167">
<rect key="frame" x="3" y="2" width="32" height="32"/>
<rect key="frame" x="3" y="-1" width="32" height="38"/>
<constraints>
<constraint firstAttribute="height" constant="32" id="168"/>
<constraint firstAttribute="width" constant="32" id="169"/>
@@ -164,7 +164,7 @@
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="NSActionTemplate" id="170"/>
</imageView>
<textField horizontalHuggingPriority="249" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="166">
<rect key="frame" x="41" y="10" width="158" height="17"/>
<rect key="frame" x="41" y="10" width="131" height="16"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="171">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@@ -172,7 +172,7 @@
</textFieldCell>
</textField>
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="42g-QS-XtW">
<rect key="frame" x="205" y="6" width="40" height="23"/>
<rect key="frame" x="175" y="4" width="54" height="25"/>
<popUpButtonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" alignment="center" lineBreakMode="truncatingTail" borderStyle="border" imageScaling="proportionallyDown" inset="2" pullsDown="YES" altersStateOfSelectedItem="NO" id="nJc-UT-cas">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="menu"/>
@@ -259,182 +259,13 @@
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="82" secondAttribute="trailing" constant="20" symbolic="YES" id="4df-0Y-ggz"/>
<constraint firstItem="82" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="3" secondAttribute="leading" constant="20" symbolic="YES" id="zU6-5h-Swa"/>
</constraints>
<point key="canvasLocation" x="391" y="-865"/>
<point key="canvasLocation" x="-680" y="-1408"/>
</view>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="4" customClass="HNHUIScrollDocumentViewAdapter">
<rect key="frame" x="0.0" y="0.0" width="291" height="712"/>
<rect key="frame" x="0.0" y="0.0" width="291" height="484"/>
<subviews>
<textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="52">
<rect key="frame" x="18" y="693" width="27" height="14"/>
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Title" id="71">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="disabledControlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="249" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="53" customClass="HNHUITextField">
<rect key="frame" x="20" y="663" width="251" height="22"/>
<constraints>
<constraint firstAttribute="height" constant="22" id="7Xj-3i-fBY"/>
</constraints>
<textFieldCell key="cell" lineBreakMode="truncatingTail" truncatesLastVisibleLine="YES" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" usesSingleLineMode="YES" id="70">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<outlet property="delegate" destination="-2" id="pQH-Xf-3pz"/>
<outlet property="nextKeyView" destination="55" id="FgE-cj-E5Z"/>
</connections>
</textField>
<textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="54">
<rect key="frame" x="18" y="637" width="58" height="14"/>
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Username" id="69">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="disabledControlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="249" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="55" customClass="HNHUITextField">
<rect key="frame" x="20" y="607" width="251" height="22"/>
<constraints>
<constraint firstAttribute="height" constant="22" id="0l5-fD-0eW"/>
</constraints>
<textFieldCell key="cell" lineBreakMode="truncatingTail" truncatesLastVisibleLine="YES" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" usesSingleLineMode="YES" id="68">
<font key="font" size="13" name="Menlo-Regular"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<outlet property="delegate" destination="-2" id="22y-I8-aaG"/>
<outlet property="nextKeyView" destination="60" id="ZPp-lg-TBS"/>
</connections>
</textField>
<textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="56" customClass="HNHUITextField">
<rect key="frame" x="20" y="469" width="251" height="22"/>
<constraints>
<constraint firstAttribute="height" constant="22" id="SoS-8e-rkN"/>
</constraints>
<textFieldCell key="cell" lineBreakMode="truncatingTail" truncatesLastVisibleLine="YES" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" usesSingleLineMode="YES" id="67">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<outlet property="delegate" destination="-2" id="LzV-u6-mkP"/>
<outlet property="nextKeyView" destination="7" id="8Vo-ZR-aWE"/>
</connections>
</textField>
<textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="57">
<rect key="frame" x="18" y="499" width="26" height="14"/>
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="URL" id="66">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="disabledControlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="58">
<rect key="frame" x="18" y="581" width="55" height="14"/>
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Password" id="65">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="disabledControlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="59">
<rect key="frame" x="20" y="520" width="251" height="23"/>
<buttonCell key="cell" type="roundTextured" title="Generate" bezelStyle="texturedRounded" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="64">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="showPasswordGenerator:" target="-2" id="xxV-lD-L1K"/>
<outlet property="nextKeyView" destination="56" id="rY0-PH-WBT"/>
</connections>
</button>
<secureTextField verticalHuggingPriority="750" horizontalCompressionResistancePriority="249" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="60" customClass="HNHUISecureTextField">
<rect key="frame" x="20" y="551" width="211" height="22"/>
<constraints>
<constraint firstAttribute="height" constant="22" id="VFI-jo-tOU"/>
</constraints>
<secureTextFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" usesSingleLineMode="YES" id="63">
<font key="font" size="13" name="Menlo-Regular"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
<allowedInputSourceLocales>
<string>NSAllRomanInputSourcesLocaleIdentifier</string>
</allowedInputSourceLocales>
</secureTextFieldCell>
<connections>
<outlet property="delegate" destination="-2" id="RBf-26-U9y"/>
<outlet property="nextKeyView" destination="61" id="5yc-GS-oVG"/>
</connections>
</secureTextField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="61">
<rect key="frame" x="239" y="550" width="32" height="23"/>
<constraints>
<constraint firstAttribute="width" constant="32" id="rSr-fw-11t"/>
</constraints>
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="NSQuickLookTemplate" imagePosition="only" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="62">
<behavior key="behavior" pushIn="YES" changeContents="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<outlet property="nextKeyView" destination="59" id="ZRe-l9-kNq"/>
</connections>
</button>
<button horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="7">
<rect key="frame" x="18" y="441" width="67" height="18"/>
<constraints>
<constraint firstAttribute="height" constant="14" id="vgc-Xu-RJs"/>
</constraints>
<buttonCell key="cell" type="check" title="Expires" bezelStyle="regularSquare" imagePosition="left" lineBreakMode="truncatingMiddle" state="on" inset="2" id="78">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="toggleExpire:" target="-2" id="EBe-2q-ASh"/>
<outlet property="nextKeyView" destination="8" id="SbJ-ZA-mXZ"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="8">
<rect key="frame" x="239" y="438" width="32" height="23"/>
<constraints>
<constraint firstAttribute="width" constant="32" id="Ped-nx-uti"/>
</constraints>
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="NSActionTemplate" imagePosition="only" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="77">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="pickExpiryDate:" target="-1" id="DQK-sp-SIL"/>
<outlet property="nextKeyView" destination="5" id="cVg-qt-OBX"/>
</connections>
</button>
<tokenField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5">
<rect key="frame" x="20" y="332" width="251" height="77"/>
<constraints>
<constraint firstAttribute="height" constant="77" id="80"/>
</constraints>
<tokenFieldCell key="cell" selectable="YES" editable="YES" borderStyle="bezel" alignment="left" drawsBackground="YES" allowsEditingTextAttributes="YES" id="81">
<font key="font" metaFont="cellTitle"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</tokenFieldCell>
<connections>
<outlet property="nextKeyView" destination="193" id="Kb5-0L-Lkd"/>
</connections>
</tokenField>
<textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6">
<rect key="frame" x="18" y="417" width="29" height="14"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Tags" id="79">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="disabledControlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="249" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="0U8-TS-giU">
<rect key="frame" x="18" y="80" width="32" height="14"/>
<rect key="frame" x="18" y="77" width="32" height="14"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" title="UUID" id="vTq-N1-5oa">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="disabledControlTextColor" catalog="System" colorSpace="catalog"/>
@@ -442,10 +273,7 @@
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="249" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="IpW-b2-jWu" customClass="HNHUITextField">
<rect key="frame" x="20" y="50" width="251" height="22"/>
<constraints>
<constraint firstAttribute="height" constant="22" id="Zfy-mh-1TF"/>
</constraints>
<rect key="frame" x="20" y="48" width="251" height="21"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="Hml-NR-AeS">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@@ -456,7 +284,7 @@
</connections>
</textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="QSX-Xo-tcH">
<rect key="frame" x="20" y="19" width="251" height="23"/>
<rect key="frame" x="19" y="18" width="253" height="23"/>
<buttonCell key="cell" type="roundTextured" title="Show Plugin Data" bezelStyle="texturedRounded" alignment="center" lineBreakMode="truncatingTail" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="X9y-K7-lix">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
@@ -467,7 +295,7 @@
</connections>
</button>
<segmentedControl verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="G9J-nn-2bu" customClass="MPContextButton">
<rect key="frame" x="216" y="101" width="55" height="23"/>
<rect key="frame" x="219" y="98" width="54" height="24"/>
<segmentedCell key="cell" borderStyle="border" alignment="left" style="texturedRounded" trackingMode="selectOne" id="POU-2t-8fl">
<font key="font" metaFont="system"/>
<segments>
@@ -480,68 +308,238 @@
<outlet property="nextKeyView" destination="QSX-Xo-tcH" id="P9m-Wl-V3E"/>
</connections>
</segmentedControl>
<stackView distribution="fill" orientation="vertical" alignment="leading" horizontalStackHuggingPriority="250" verticalStackHuggingPriority="250" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="dx3-E2-FFt">
<rect key="frame" x="20" y="135" width="251" height="329"/>
<subviews>
<textField horizontalHuggingPriority="249" verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="52">
<rect key="frame" x="-2" y="315" width="255" height="14"/>
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Title" id="71">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="disabledControlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="249" verticalHuggingPriority="750" horizontalCompressionResistancePriority="249" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="53" customClass="HNHUITextField">
<rect key="frame" x="0.0" y="286" width="251" height="21"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" truncatesLastVisibleLine="YES" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" usesSingleLineMode="YES" id="70">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<outlet property="delegate" destination="-2" id="pQH-Xf-3pz"/>
<outlet property="nextKeyView" destination="55" id="FgE-cj-E5Z"/>
</connections>
</textField>
<textField horizontalHuggingPriority="249" verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="54">
<rect key="frame" x="-2" y="264" width="255" height="14"/>
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Username" id="69">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="disabledControlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="249" verticalHuggingPriority="750" horizontalCompressionResistancePriority="249" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="55" customClass="HNHUITextField">
<rect key="frame" x="0.0" y="236" width="251" height="20"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" truncatesLastVisibleLine="YES" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" usesSingleLineMode="YES" id="68">
<font key="font" size="13" name="Menlo-Regular"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<outlet property="delegate" destination="-2" id="22y-I8-aaG"/>
<outlet property="nextKeyView" destination="60" id="ZPp-lg-TBS"/>
</connections>
</textField>
<textField horizontalHuggingPriority="249" verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="58">
<rect key="frame" x="-2" y="214" width="255" height="14"/>
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Password" id="65">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="disabledControlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<stackView distribution="fill" orientation="horizontal" alignment="centerY" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" horizontalHuggingPriority="249" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="C4J-K4-QBG">
<rect key="frame" x="0.0" y="186" width="251" height="20"/>
<subviews>
<secureTextField horizontalHuggingPriority="249" verticalHuggingPriority="750" horizontalCompressionResistancePriority="249" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="60" customClass="HNHUISecureTextField">
<rect key="frame" x="0.0" y="0.0" width="135" height="20"/>
<secureTextFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" usesSingleLineMode="YES" id="63" customClass="HNHUISecureTextFieldCell">
<font key="font" size="13" name="Menlo-Regular"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
<allowedInputSourceLocales>
<string>NSAllRomanInputSourcesLocaleIdentifier</string>
</allowedInputSourceLocales>
</secureTextFieldCell>
<connections>
<outlet property="delegate" destination="-2" id="RBf-26-U9y"/>
<outlet property="nextKeyView" destination="61" id="5yc-GS-oVG"/>
</connections>
</secureTextField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="61">
<rect key="frame" x="142" y="-2" width="32" height="23"/>
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="NSQuickLookTemplate" imagePosition="only" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="62">
<behavior key="behavior" pushIn="YES" changeContents="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<outlet property="nextKeyView" destination="59" id="ZRe-l9-kNq"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="59">
<rect key="frame" x="180" y="-2" width="72" height="23"/>
<buttonCell key="cell" type="roundTextured" title="Generate" bezelStyle="texturedRounded" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="64">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="showPasswordGenerator:" target="-2" id="xxV-lD-L1K"/>
<outlet property="nextKeyView" destination="56" id="rY0-PH-WBT"/>
</connections>
</button>
</subviews>
<visibilityPriorities>
<integer value="1000"/>
<integer value="1000"/>
<integer value="1000"/>
</visibilityPriorities>
<customSpacing>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
</customSpacing>
</stackView>
<textField horizontalHuggingPriority="249" verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="57">
<rect key="frame" x="-2" y="164" width="255" height="14"/>
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="URL" id="66">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="disabledControlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="56" customClass="HNHUITextField">
<rect key="frame" x="0.0" y="135" width="251" height="21"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" truncatesLastVisibleLine="YES" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" usesSingleLineMode="YES" id="67">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<connections>
<outlet property="delegate" destination="-2" id="LzV-u6-mkP"/>
<outlet property="nextKeyView" destination="7" id="8Vo-ZR-aWE"/>
</connections>
</textField>
<stackView distribution="fill" orientation="horizontal" alignment="centerY" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" horizontalHuggingPriority="248" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="buA-UH-XId">
<rect key="frame" x="0.0" y="107" width="251" height="20"/>
<subviews>
<button horizontalHuggingPriority="249" horizontalCompressionResistancePriority="249" translatesAutoresizingMaskIntoConstraints="NO" id="7">
<rect key="frame" x="-2" y="1" width="214" height="18"/>
<buttonCell key="cell" type="check" title="Expires" bezelStyle="regularSquare" imagePosition="left" lineBreakMode="truncatingMiddle" state="on" inset="2" id="78">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="toggleExpire:" target="-2" id="EBe-2q-ASh"/>
<outlet property="nextKeyView" destination="8" id="SbJ-ZA-mXZ"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="8">
<rect key="frame" x="213" y="-7" width="45" height="32"/>
<buttonCell key="cell" type="push" bezelStyle="rounded" image="NSActionTemplate" imagePosition="only" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="77">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="pickExpiryDate:" target="-1" id="DQK-sp-SIL"/>
<outlet property="nextKeyView" destination="5" id="cVg-qt-OBX"/>
</connections>
</button>
</subviews>
<visibilityPriorities>
<integer value="1000"/>
<integer value="1000"/>
</visibilityPriorities>
<customSpacing>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
</customSpacing>
</stackView>
<textField horizontalHuggingPriority="249" verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6">
<rect key="frame" x="-2" y="85" width="255" height="14"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Tags" id="79">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="disabledControlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<tokenField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5">
<rect key="frame" x="0.0" y="0.0" width="251" height="77"/>
<constraints>
<constraint firstAttribute="height" constant="77" id="80"/>
</constraints>
<tokenFieldCell key="cell" selectable="YES" editable="YES" borderStyle="bezel" alignment="left" drawsBackground="YES" allowsEditingTextAttributes="YES" id="81">
<font key="font" metaFont="cellTitle"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</tokenFieldCell>
<connections>
<outlet property="nextKeyView" destination="193" id="Kb5-0L-Lkd"/>
</connections>
</tokenField>
</subviews>
<visibilityPriorities>
<integer value="1000"/>
<integer value="1000"/>
<integer value="1000"/>
<integer value="1000"/>
<integer value="1000"/>
<integer value="1000"/>
<integer value="1000"/>
<integer value="1000"/>
<integer value="1000"/>
<integer value="1000"/>
<integer value="1000"/>
</visibilityPriorities>
<customSpacing>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
</customSpacing>
</stackView>
</subviews>
<constraints>
<constraint firstItem="52" firstAttribute="top" secondItem="4" secondAttribute="top" constant="5" id="11"/>
<constraint firstItem="52" firstAttribute="leading" secondItem="4" secondAttribute="leading" constant="20" symbolic="YES" id="12"/>
<constraint firstItem="53" firstAttribute="leading" secondItem="4" secondAttribute="leading" constant="20" symbolic="YES" id="13"/>
<constraint firstItem="53" firstAttribute="top" secondItem="52" secondAttribute="bottom" constant="8" symbolic="YES" id="14"/>
<constraint firstAttribute="trailing" secondItem="53" secondAttribute="trailing" constant="20" symbolic="YES" id="15"/>
<constraint firstItem="54" firstAttribute="leading" secondItem="4" secondAttribute="leading" constant="20" symbolic="YES" id="16"/>
<constraint firstItem="54" firstAttribute="top" secondItem="53" secondAttribute="bottom" constant="12" id="17"/>
<constraint firstItem="55" firstAttribute="leading" secondItem="4" secondAttribute="leading" constant="20" symbolic="YES" id="18"/>
<constraint firstItem="55" firstAttribute="top" secondItem="54" secondAttribute="bottom" constant="8" symbolic="YES" id="19"/>
<constraint firstAttribute="trailing" secondItem="55" secondAttribute="trailing" constant="20" symbolic="YES" id="20"/>
<constraint firstItem="57" firstAttribute="leading" secondItem="4" secondAttribute="leading" constant="20" symbolic="YES" id="21"/>
<constraint firstItem="56" firstAttribute="leading" secondItem="4" secondAttribute="leading" constant="20" symbolic="YES" id="23"/>
<constraint firstItem="56" firstAttribute="top" secondItem="57" secondAttribute="bottom" constant="8" symbolic="YES" id="24"/>
<constraint firstAttribute="trailing" secondItem="56" secondAttribute="trailing" constant="20" symbolic="YES" id="25"/>
<constraint firstItem="58" firstAttribute="leading" secondItem="4" secondAttribute="leading" constant="20" symbolic="YES" id="26"/>
<constraint firstItem="60" firstAttribute="top" secondItem="58" secondAttribute="bottom" constant="8" symbolic="YES" id="29"/>
<constraint firstItem="60" firstAttribute="leading" secondItem="4" secondAttribute="leading" constant="20" symbolic="YES" id="30"/>
<constraint firstItem="59" firstAttribute="top" secondItem="61" secondAttribute="bottom" constant="8" symbolic="YES" id="31"/>
<constraint firstItem="59" firstAttribute="top" secondItem="60" secondAttribute="bottom" constant="8" symbolic="YES" id="32"/>
<constraint firstItem="59" firstAttribute="leading" secondItem="4" secondAttribute="leading" constant="20" symbolic="YES" id="33"/>
<constraint firstAttribute="trailing" secondItem="59" secondAttribute="trailing" constant="20" symbolic="YES" id="34"/>
<constraint firstItem="61" firstAttribute="leading" secondItem="60" secondAttribute="trailing" constant="8" symbolic="YES" id="40"/>
<constraint firstAttribute="trailing" secondItem="61" secondAttribute="trailing" constant="20" symbolic="YES" id="41"/>
<constraint firstItem="7" firstAttribute="leading" secondItem="4" secondAttribute="leading" constant="20" symbolic="YES" id="42"/>
<constraint firstItem="7" firstAttribute="centerY" secondItem="8" secondAttribute="centerY" id="43"/>
<constraint firstItem="6" firstAttribute="top" secondItem="7" secondAttribute="bottom" constant="12" id="44"/>
<constraint firstItem="6" firstAttribute="leading" secondItem="4" secondAttribute="leading" constant="20" symbolic="YES" id="45"/>
<constraint firstAttribute="trailing" secondItem="8" secondAttribute="trailing" constant="20" symbolic="YES" id="47"/>
<constraint firstItem="5" firstAttribute="top" secondItem="6" secondAttribute="bottom" constant="8" symbolic="YES" id="48"/>
<constraint firstItem="5" firstAttribute="leading" secondItem="4" secondAttribute="leading" constant="20" symbolic="YES" id="49"/>
<constraint firstAttribute="trailing" secondItem="5" secondAttribute="trailing" constant="20" symbolic="YES" id="50"/>
<constraint firstItem="QSX-Xo-tcH" firstAttribute="leading" secondItem="4" secondAttribute="leading" constant="20" symbolic="YES" id="2AA-hQ-mL7"/>
<constraint firstItem="IpW-b2-jWu" firstAttribute="leading" secondItem="4" secondAttribute="leading" constant="20" id="51R-pR-KLO"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="52" secondAttribute="trailing" constant="20" symbolic="YES" id="6P6-fW-kGx"/>
<constraint firstAttribute="trailing" secondItem="IpW-b2-jWu" secondAttribute="trailing" constant="20" id="D0t-s7-2hT"/>
<constraint firstItem="7" firstAttribute="top" secondItem="56" secondAttribute="bottom" constant="12" id="Gh9-Lg-kcm"/>
<constraint firstAttribute="bottom" secondItem="QSX-Xo-tcH" secondAttribute="bottom" constant="20" symbolic="YES" id="Fpp-iu-smS"/>
<constraint firstItem="IpW-b2-jWu" firstAttribute="top" secondItem="0U8-TS-giU" secondAttribute="bottom" constant="8" symbolic="YES" id="HSM-Aj-X9I"/>
<constraint firstItem="58" firstAttribute="top" secondItem="55" secondAttribute="bottom" constant="12" id="JiM-Dm-AG8"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="57" secondAttribute="trailing" constant="20" symbolic="YES" id="N4A-wg-PdS"/>
<constraint firstItem="QSX-Xo-tcH" firstAttribute="top" secondItem="IpW-b2-jWu" secondAttribute="bottom" constant="8" symbolic="YES" id="TPp-cx-48q"/>
<constraint firstItem="8" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="7" secondAttribute="trailing" constant="8" symbolic="YES" id="Xa5-Ir-XNC"/>
<constraint firstAttribute="bottom" secondItem="QSX-Xo-tcH" secondAttribute="bottom" constant="20" symbolic="YES" id="ZdF-5c-xDa"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="0U8-TS-giU" secondAttribute="trailing" constant="20" symbolic="YES" id="a5R-eI-VuV"/>
<constraint firstItem="0U8-TS-giU" firstAttribute="top" secondItem="G9J-nn-2bu" secondAttribute="bottom" constant="8" symbolic="YES" id="aes-tv-LHA"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="54" secondAttribute="trailing" constant="20" symbolic="YES" id="cYP-oK-dVP"/>
<constraint firstAttribute="trailing" secondItem="dx3-E2-FFt" secondAttribute="trailing" constant="20" symbolic="YES" id="esd-fR-ZGC"/>
<constraint firstAttribute="trailing" secondItem="G9J-nn-2bu" secondAttribute="trailing" constant="20" symbolic="YES" id="ggu-f5-LtR"/>
<constraint firstAttribute="trailing" secondItem="QSX-Xo-tcH" secondAttribute="trailing" constant="20" symbolic="YES" id="hr2-Eb-g24"/>
<constraint firstItem="dx3-E2-FFt" firstAttribute="top" secondItem="4" secondAttribute="top" constant="20" symbolic="YES" id="k31-5b-7n6"/>
<constraint firstItem="0U8-TS-giU" firstAttribute="leading" secondItem="4" secondAttribute="leading" constant="20" id="kLH-Bj-C5m"/>
<constraint firstItem="57" firstAttribute="top" secondItem="59" secondAttribute="bottom" constant="8" symbolic="YES" id="lYe-am-xJx"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="58" secondAttribute="trailing" constant="20" symbolic="YES" id="rbs-i7-bti"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="6" secondAttribute="trailing" constant="20" symbolic="YES" id="uuh-ba-z4h"/>
<constraint firstItem="dx3-E2-FFt" firstAttribute="leading" secondItem="4" secondAttribute="leading" constant="20" symbolic="YES" id="sjr-Xo-zxh"/>
<constraint firstItem="G9J-nn-2bu" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="4" secondAttribute="leading" constant="20" symbolic="YES" id="z4K-PB-Qfb"/>
</constraints>
<point key="canvasLocation" x="-679" y="-1054"/>
<point key="canvasLocation" x="-304" y="-1442"/>
</customView>
<view translatesAutoresizingMaskIntoConstraints="NO" id="zv7-wE-Bmg" customClass="HNHUIScrollDocumentViewAdapter">
<rect key="frame" x="0.0" y="0.0" width="301" height="424"/>
<subviews>
<button translatesAutoresizingMaskIntoConstraints="NO" id="kdV-Xa-8p3">
<rect key="frame" x="18" y="398" width="265" height="18"/>
<rect key="frame" x="18" y="399" width="263" height="16"/>
<constraints>
<constraint firstAttribute="height" constant="14" id="c9A-Ju-Cj9"/>
</constraints>
@@ -551,7 +549,7 @@
</buttonCell>
</button>
<button translatesAutoresizingMaskIntoConstraints="NO" id="I7L-Am-Qpa">
<rect key="frame" x="18" y="378" width="265" height="18"/>
<rect key="frame" x="18" y="379" width="263" height="16"/>
<constraints>
<constraint firstAttribute="height" constant="14" id="KKP-xg-uUu"/>
</constraints>
@@ -569,10 +567,7 @@
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="cDK-DM-F5z" customClass="HNHUITextField">
<rect key="frame" x="20" y="328" width="221" height="22"/>
<constraints>
<constraint firstAttribute="height" constant="22" id="2hC-UP-Iie"/>
</constraints>
<rect key="frame" x="20" y="329" width="228" height="21"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" placeholderString="Custom Entry Sequence" drawsBackground="YES" id="R2X-Ex-c6q">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@@ -580,7 +575,7 @@
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="iR3-FU-MYu">
<rect key="frame" x="18" y="306" width="265" height="14"/>
<rect key="frame" x="18" y="307" width="265" height="14"/>
<constraints>
<constraint firstAttribute="height" constant="14" id="xvF-LU-XNu"/>
</constraints>
@@ -591,21 +586,20 @@
</textFieldCell>
</textField>
<scrollView autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="2YH-c2-Cwc">
<rect key="frame" x="20" y="138" width="261" height="160"/>
<rect key="frame" x="20" y="136" width="261" height="163"/>
<clipView key="contentView" id="aDE-WT-YIv">
<rect key="frame" x="1" y="1" width="259" height="158"/>
<rect key="frame" x="1" y="1" width="259" height="161"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" alternatingRowBackgroundColors="YES" columnReordering="NO" columnSelection="YES" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" rowSizeStyle="automatic" viewBased="YES" id="caM-L6-UHC">
<rect key="frame" x="0.0" y="0.0" width="259" height="158"/>
<autoresizingMask key="autoresizingMask"/>
<rect key="frame" x="0.0" y="0.0" width="259" height="161"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
<tableColumns>
<tableColumn width="256" minWidth="40" maxWidth="1000" id="Wdn-k1-39b">
<tableColumn width="247" minWidth="40" maxWidth="1000" id="Wdn-k1-39b">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" white="0.33333298560000002" alpha="1" colorSpace="calibratedWhite"/>
</tableHeaderCell>
@@ -651,10 +645,7 @@
</scroller>
</scrollView>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Iy9-9L-Aev">
<rect key="frame" x="249" y="107" width="32" height="23"/>
<constraints>
<constraint firstAttribute="width" constant="32" id="mjs-Yf-Cb2"/>
</constraints>
<rect key="frame" x="256" y="106" width="26" height="23"/>
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="NSAddTemplate" imagePosition="only" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="5J6-uD-iK6">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
@@ -664,10 +655,7 @@
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="AAj-Ak-z46">
<rect key="frame" x="209" y="107" width="32" height="23"/>
<constraints>
<constraint firstAttribute="width" constant="32" id="vWY-ez-gy9"/>
</constraints>
<rect key="frame" x="224" y="106" width="26" height="23"/>
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="NSRemoveTemplate" imagePosition="only" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="86n-d4-lOW">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
@@ -677,7 +665,7 @@
</connections>
</button>
<textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="HQa-of-iwh">
<rect key="frame" x="18" y="90" width="265" height="14"/>
<rect key="frame" x="18" y="88" width="265" height="14"/>
<constraints>
<constraint firstAttribute="height" constant="14" id="GF5-sR-zdR"/>
</constraints>
@@ -688,10 +676,7 @@
</textFieldCell>
</textField>
<comboBox verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="rD3-Wn-ZFX">
<rect key="frame" x="20" y="58" width="264" height="26"/>
<constraints>
<constraint firstAttribute="height" constant="20" id="rXS-QE-6cW"/>
</constraints>
<rect key="frame" x="20" y="57" width="264" height="25"/>
<comboBoxCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" completes="NO" id="VLq-Hn-aei">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@@ -699,7 +684,7 @@
</comboBoxCell>
</comboBox>
<textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="z03-zW-GN3">
<rect key="frame" x="18" y="40" width="265" height="14"/>
<rect key="frame" x="18" y="39" width="265" height="14"/>
<constraints>
<constraint firstAttribute="height" constant="14" id="MPq-gU-72D"/>
</constraints>
@@ -710,10 +695,7 @@
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="NjR-ea-Y7k" customClass="HNHUITextField">
<rect key="frame" x="20" y="10" width="221" height="22"/>
<constraints>
<constraint firstAttribute="height" constant="22" id="oIA-8f-Jkf"/>
</constraints>
<rect key="frame" x="20" y="10" width="228" height="21"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" placeholderString="Custom Window Sequence" drawsBackground="YES" id="fW9-9p-wwR">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@@ -721,10 +703,7 @@
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="m1C-m8-BKR">
<rect key="frame" x="249" y="9" width="32" height="23"/>
<constraints>
<constraint firstAttribute="width" constant="32" id="Ek5-IH-qGo"/>
</constraints>
<rect key="frame" x="255" y="9" width="27" height="23"/>
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="NSActionTemplate" imagePosition="only" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="HIC-T9-j9G">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
@@ -734,10 +713,7 @@
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="HDS-Bz-jrr">
<rect key="frame" x="249" y="326" width="32" height="23"/>
<constraints>
<constraint firstAttribute="width" constant="32" id="CbR-2P-dZH"/>
</constraints>
<rect key="frame" x="255" y="327" width="27" height="23"/>
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="NSActionTemplate" imagePosition="only" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="V5Z-qf-FVH">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
@@ -788,24 +764,23 @@
<constraint firstAttribute="trailing" secondItem="45R-v4-ywl" secondAttribute="trailing" constant="20" symbolic="YES" id="uUm-S5-cxM"/>
<constraint firstAttribute="trailing" secondItem="z03-zW-GN3" secondAttribute="trailing" constant="20" symbolic="YES" id="wiq-pY-TG8"/>
</constraints>
<point key="canvasLocation" x="39" y="-995"/>
<point key="canvasLocation" x="146" y="-1275"/>
</view>
<scrollView borderType="line" autohidesScrollers="YES" horizontalLineScroll="56" horizontalPageScroll="10" verticalLineScroll="56" verticalPageScroll="10" usesPredominantAxisScrolling="NO" horizontalScrollElasticity="none" translatesAutoresizingMaskIntoConstraints="NO" id="180" customClass="HNHUIScrollView">
<rect key="frame" x="0.0" y="0.0" width="261" height="270"/>
<rect key="frame" x="0.0" y="0.0" width="261" height="268"/>
<clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="k8G-zp-BXZ">
<rect key="frame" x="1" y="1" width="259" height="268"/>
<rect key="frame" x="1" y="1" width="259" height="266"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" selectionHighlightStyle="none" columnSelection="YES" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" rowHeight="54" viewBased="YES" id="193" customClass="MPCustomFieldTableView">
<rect key="frame" x="0.0" y="0.0" width="259" height="268"/>
<autoresizingMask key="autoresizingMask"/>
<tableView focusRingType="none" verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" selectionHighlightStyle="none" columnSelection="YES" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" rowHeight="54" viewBased="YES" id="193">
<rect key="frame" x="0.0" y="0.0" width="259" height="266"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
<tableColumns>
<tableColumn width="256" minWidth="40" maxWidth="1000000" id="194">
<tableColumn width="247" minWidth="40" maxWidth="1000000" id="194">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" white="0.33333298560000002" alpha="1" colorSpace="calibratedWhite"/>
</tableHeaderCell>
@@ -817,23 +792,22 @@
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES"/>
<prototypeCellViews>
<tableCellView identifier="SelectedCell" id="196" customClass="MPCustomFieldTableCellView">
<rect key="frame" x="1" y="1" width="256" height="54"/>
<rect key="frame" x="1" y="1" width="256" height="53"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="199" customClass="HNHUISecureTextField">
<rect key="frame" x="3" y="10" width="139" height="22"/>
<rect key="frame" x="3" y="10" width="153" height="21"/>
<constraints>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="22" id="212"/>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="50" id="213"/>
</constraints>
<textFieldCell key="cell" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" placeholderString="Value" drawsBackground="YES" id="214">
<textFieldCell key="cell" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" placeholderString="Value" drawsBackground="YES" id="214" customClass="HNHUISecureTextFieldCell">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="200">
<rect key="frame" x="1" y="40" width="223" height="14"/>
<rect key="frame" x="1" y="39" width="223" height="14"/>
<constraints>
<constraint firstAttribute="height" constant="14" id="210"/>
</constraints>
@@ -844,20 +818,14 @@
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="198">
<rect key="frame" x="190" y="9" width="32" height="23"/>
<constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="32" id="215"/>
</constraints>
<rect key="frame" x="197" y="9" width="26" height="23"/>
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="NSRemoveTemplate" imagePosition="overlaps" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="216">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="tDI-EL-JGB">
<rect key="frame" x="150" y="9" width="32" height="23"/>
<constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="32" id="JGO-sl-fdM"/>
</constraints>
<rect key="frame" x="163" y="9" width="28" height="23"/>
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="52_EncryptedTemplate" imagePosition="overlaps" alignment="center" lineBreakMode="truncatingTail" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="fat-C5-dS2">
<behavior key="behavior" pushIn="YES" changeContents="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
@@ -902,14 +870,14 @@
<connections>
<outlet property="nextKeyView" destination="G9J-nn-2bu" id="CZ9-f2-JDQ"/>
</connections>
<point key="canvasLocation" x="-1317" y="-1440"/>
<point key="canvasLocation" x="-1015" y="-1275"/>
</scrollView>
</objects>
<resources>
<image name="52_EncryptedTemplate" width="16" height="16"/>
<image name="NSActionTemplate" width="14" height="14"/>
<image name="NSAddTemplate" width="11" height="11"/>
<image name="NSQuickLookTemplate" width="19" height="12"/>
<image name="NSRemoveTemplate" width="11" height="11"/>
<image name="NSActionTemplate" width="15" height="15"/>
<image name="NSAddTemplate" width="14" height="13"/>
<image name="NSQuickLookTemplate" width="21" height="13"/>
<image name="NSRemoveTemplate" width="14" height="4"/>
</resources>
</document>

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="15702" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="15705" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15702"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15705"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@@ -11,6 +11,7 @@
<outlet property="clearPasteboardOnQuitCheckButton" destination="447" id="520"/>
<outlet property="clearPasteboardTimeoutPopup" destination="419" id="521"/>
<outlet property="enableAutosaveCheckButton" destination="lz3-4U-UMI" id="L5y-58-IgH"/>
<outlet property="faviconDownloadMethodPopup" destination="OfU-6f-oTU" id="OfU-6f-oTU-outlet"/>
<outlet property="fileChangeStrategyPopup" destination="wIu-Sh-2a2" id="oJo-dA-lEE"/>
<outlet property="idleTimeOutPopup" destination="584" id="809"/>
<outlet property="lockOnLogoutCheckButton" destination="5SP-Vi-1sn" id="yaI-LH-R5A"/>
@@ -25,12 +26,12 @@
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="1">
<rect key="frame" x="0.0" y="0.0" width="411" height="547"/>
<rect key="frame" x="0.0" y="0.0" width="406" height="679"/>
<subviews>
<box autoresizesSubviews="NO" verticalHuggingPriority="500" borderType="line" title="Security" translatesAutoresizingMaskIntoConstraints="NO" id="465">
<rect key="frame" x="17" y="16" width="377" height="381"/>
<rect key="frame" x="17" y="146" width="372" height="381"/>
<view key="contentView" id="mNh-3L-Z6E">
<rect key="frame" x="3" y="3" width="371" height="363"/>
<rect key="frame" x="3" y="3" width="366" height="363"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="431">
@@ -48,7 +49,7 @@
<rect key="frame" x="138" y="332" width="143" height="21"/>
<popUpButtonCell key="cell" type="push" title="Never" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="429" id="420">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<font key="font" metaFont="menu"/>
<menu key="menu" title="ClipboardClearInterval" id="421">
<items>
<menuItem title="Never" state="on" id="429">
@@ -76,7 +77,7 @@
<rect key="frame" x="111" y="192" width="125" height="25"/>
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="585">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<font key="font" metaFont="menu"/>
<menu key="menu" title="LockTimes" id="586">
<items>
<menuItem title="Never" id="804"/>
@@ -111,8 +112,8 @@
<font key="font" metaFont="system"/>
</buttonCell>
</button>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="5cV-xX-SUU">
<rect key="frame" x="18" y="41" width="335" height="56"/>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="5cV-xX-SUU">
<rect key="frame" x="18" y="41" width="330" height="56"/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" id="ACh-7H-42N">
<font key="font" metaFont="smallSystem"/>
<string key="title">Enabling this compromises security. If enabled, your preferences will contain mappings from database to keyfile. Key locations for databases without a password will not be saved.</string>
@@ -121,7 +122,7 @@
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="oQr-FC-HkN">
<rect key="frame" x="171" y="5" width="190" height="32"/>
<rect key="frame" x="166" y="5" width="190" height="32"/>
<buttonCell key="cell" type="push" title="Clear all stored locations" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="8Ri-2s-c39">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
@@ -144,8 +145,8 @@
<font key="font" metaFont="system"/>
</buttonCell>
</button>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="hy4-RL-dAa">
<rect key="frame" x="18" y="224" width="335" height="56"/>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="hy4-RL-dAa">
<rect key="frame" x="18" y="224" width="330" height="56"/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" id="JGX-Tp-KJk">
<font key="font" metaFont="smallSystem"/>
<string key="title">Disabling this compromises security. If enabled, anything copied to the Clipboard in MacPass will be available on your connected iOS devices. You should clear the clipboard on those devices manually.</string>
@@ -208,9 +209,9 @@
</constraints>
</box>
<box autoresizesSubviews="NO" verticalHuggingPriority="500" borderType="line" title="File Handling" translatesAutoresizingMaskIntoConstraints="NO" id="888">
<rect key="frame" x="17" y="399" width="377" height="128"/>
<rect key="frame" x="17" y="531" width="372" height="128"/>
<view key="contentView" id="cpg-tt-SHE">
<rect key="frame" x="3" y="3" width="371" height="110"/>
<rect key="frame" x="3" y="3" width="366" height="110"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<button verticalHuggingPriority="252" translatesAutoresizingMaskIntoConstraints="NO" id="530">
@@ -227,8 +228,8 @@
<font key="font" metaFont="system"/>
</buttonCell>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="3Bo-Ml-1KB">
<rect key="frame" x="18" y="44" width="335" height="14"/>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="3Bo-Ml-1KB">
<rect key="frame" x="18" y="44" width="330" height="14"/>
<textFieldCell key="cell" controlSize="small" title="Close and open all documents for changes to take effect" id="ya5-ps-c4W">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@@ -247,7 +248,7 @@
<rect key="frame" x="111" y="13" width="38" height="25"/>
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="1R2-5t-LWk">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<font key="font" metaFont="menu"/>
<menu key="menu" id="DQY-17-yKP"/>
</popUpButtonCell>
</popUpButton>
@@ -273,18 +274,71 @@
<constraint firstItem="530" firstAttribute="top" secondItem="888" secondAttribute="top" constant="25" id="w7t-Jm-kXg"/>
</constraints>
</box>
<box autoresizesSubviews="NO" verticalHuggingPriority="500" borderType="line" title="Network" translatesAutoresizingMaskIntoConstraints="NO" id="wD1-ag-7V5">
<rect key="frame" x="17" y="16" width="372" height="126"/>
<view key="contentView" id="bQD-ZX-d0i">
<rect key="frame" x="3" y="3" width="366" height="108"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="fl5-Xu-nZP">
<rect key="frame" x="14" y="81" width="113" height="16"/>
<constraints>
<constraint firstAttribute="height" constant="16" id="kK7-bB-zKY"/>
</constraints>
<textFieldCell key="cell" lineBreakMode="clipping" title="Favicon download" id="YGj-dH-duz">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField autoresizesSubviews="NO" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="MWj-9m-uGk">
<rect key="frame" x="18" y="13" width="330" height="56"/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" id="DaG-1a-SET">
<font key="font" metaFont="message" size="11"/>
<string key="title">By default web site icon is downloaded directly from entry's host URL. For some websites it doesn't work and you might prefer using 3rdparty APIs. In this case only host from the URL will be used to get the icon from selected service.</string>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<popUpButton verticalHuggingPriority="750" horizontalCompressionResistancePriority="749" translatesAutoresizingMaskIntoConstraints="NO" id="OfU-6f-oTU">
<rect key="frame" x="131" y="76" width="38" height="25"/>
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="mdi-Go-1bJ">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="menu"/>
<menu key="menu" id="Xnp-a8-ePw"/>
</popUpButtonCell>
</popUpButton>
</subviews>
<constraints>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="OfU-6f-oTU" secondAttribute="trailing" constant="16" id="0Wl-LS-ePD"/>
<constraint firstItem="OfU-6f-oTU" firstAttribute="centerY" secondItem="fl5-Xu-nZP" secondAttribute="centerY" id="R81-Ij-pdy"/>
<constraint firstItem="OfU-6f-oTU" firstAttribute="leading" secondItem="fl5-Xu-nZP" secondAttribute="trailing" constant="8" id="XS0-fl-B2Z"/>
</constraints>
</view>
<constraints>
<constraint firstItem="MWj-9m-uGk" firstAttribute="leading" secondItem="bQD-ZX-d0i" secondAttribute="leading" constant="20" id="1AE-Eu-ceQ"/>
<constraint firstItem="fl5-Xu-nZP" firstAttribute="top" secondItem="wD1-ag-7V5" secondAttribute="top" constant="26" id="OK9-PR-DfC"/>
<constraint firstItem="MWj-9m-uGk" firstAttribute="top" secondItem="fl5-Xu-nZP" secondAttribute="bottom" constant="12" id="Udz-22-4O1"/>
<constraint firstAttribute="trailing" secondItem="MWj-9m-uGk" secondAttribute="trailing" constant="20" id="hA0-ra-UeU"/>
<constraint firstItem="fl5-Xu-nZP" firstAttribute="leading" secondItem="bQD-ZX-d0i" secondAttribute="leading" constant="16" id="hzo-40-wxR"/>
<constraint firstAttribute="bottom" secondItem="MWj-9m-uGk" secondAttribute="bottom" constant="12" id="k80-DD-Y5l"/>
</constraints>
</box>
</subviews>
<constraints>
<constraint firstItem="465" firstAttribute="leading" secondItem="1" secondAttribute="leading" constant="20" symbolic="YES" id="475"/>
<constraint firstAttribute="trailing" secondItem="465" secondAttribute="trailing" constant="20" symbolic="YES" id="525"/>
<constraint firstItem="888" firstAttribute="leading" secondItem="1" secondAttribute="leading" constant="20" symbolic="YES" id="891"/>
<constraint firstAttribute="trailing" secondItem="888" secondAttribute="trailing" constant="20" symbolic="YES" id="893"/>
<constraint firstItem="888" firstAttribute="top" secondItem="1" secondAttribute="top" constant="20" symbolic="YES" id="903"/>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="400" id="918"/>
<constraint firstAttribute="bottom" secondItem="465" secondAttribute="bottom" constant="20" symbolic="YES" id="uwq-az-XwJ"/>
<constraint firstItem="465" firstAttribute="top" secondItem="cpg-tt-SHE" secondAttribute="bottom" constant="5" id="wyH-HB-i2U"/>
<constraint firstItem="wD1-ag-7V5" firstAttribute="leading" secondItem="1" secondAttribute="leading" constant="20" id="3kp-Uf-fyC"/>
<constraint firstItem="wD1-ag-7V5" firstAttribute="bottom" secondItem="1" secondAttribute="bottom" constant="-20" id="EeW-K0-jec"/>
<constraint firstItem="wD1-ag-7V5" firstAttribute="top" secondItem="465" secondAttribute="bottom" constant="8" symbolic="YES" id="FsW-LX-Drs"/>
<constraint firstItem="888" firstAttribute="top" secondItem="1" secondAttribute="top" constant="20" symbolic="YES" id="ZMP-Lv-rQh"/>
<constraint firstAttribute="trailing" secondItem="wD1-ag-7V5" secondAttribute="trailing" constant="20" id="ccK-FL-7Wx"/>
<constraint firstItem="465" firstAttribute="top" secondItem="888" secondAttribute="bottom" constant="8" symbolic="YES" id="wyH-HB-i2U"/>
</constraints>
<point key="canvasLocation" x="-458" y="-295"/>
<point key="canvasLocation" x="-535" y="-327.5"/>
</customView>
</objects>
</document>

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14313.18" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17506" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14313.18"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17506"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@@ -44,7 +44,7 @@
</connections>
</imageView>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="249" translatesAutoresizingMaskIntoConstraints="NO" id="3013">
<rect key="frame" x="58" y="628" width="202" height="17"/>
<rect key="frame" x="58" y="628" width="202" height="16"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" truncatesLastVisibleLine="YES" allowsUndo="NO" sendsActionOnEndEditing="YES" title="Label" usesSingleLineMode="YES" id="3014">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@@ -83,7 +83,7 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="2985">
<rect key="frame" x="82" y="194" width="115" height="24"/>
<rect key="frame" x="82" y="194" width="115" height="23"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="No Selection" id="2986">
<font key="font" metaFont="system" size="20"/>
<color key="textColor" name="controlShadowColor" catalog="System" colorSpace="catalog"/>
@@ -200,7 +200,7 @@
<constraint firstItem="3145" firstAttribute="leading" secondItem="2894" secondAttribute="leading" id="3155"/>
<constraint firstAttribute="bottom" secondItem="3145" secondAttribute="bottom" id="PjS-Y5-YA6"/>
</constraints>
<point key="canvasLocation" x="-224" y="-890"/>
<point key="canvasLocation" x="-349" y="-997"/>
</customView>
</objects>
<resources>

View File

@@ -1,13 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17701"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="MPIntegrationPreferencesController">
<connections>
<outlet property="alwaysShowConfirmationBeforeAutotypeCheckBox" destination="uZQ-Gd-hfu" id="6NL-Tz-7su"/>
<outlet property="autotypeStackView" destination="j52-9L-k7c" id="Mxw-aa-elx"/>
<outlet property="autotypeWarningTextField" destination="hMJ-Mo-xOM" id="LcH-X2-TAm"/>
<outlet property="enableGlobalAutotypeCheckBox" destination="tik-Ar-FJg" id="yVA-bM-sSh"/>
@@ -26,19 +27,19 @@
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="1">
<rect key="frame" x="0.0" y="0.0" width="400" height="449"/>
<rect key="frame" x="0.0" y="0.0" width="417" height="664"/>
<subviews>
<box autoresizesSubviews="NO" verticalHuggingPriority="500" borderType="line" title="Autotype" translatesAutoresizingMaskIntoConstraints="NO" id="P9N-HM-wER">
<rect key="frame" x="17" y="115" width="366" height="314"/>
<rect key="frame" x="17" y="246" width="383" height="398"/>
<view key="contentView" id="faU-Ok-HJ3">
<rect key="frame" x="3" y="3" width="360" height="296"/>
<rect key="frame" x="3" y="3" width="377" height="380"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<stackView orientation="vertical" alignment="leading" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" translatesAutoresizingMaskIntoConstraints="NO" id="j52-9L-k7c">
<rect key="frame" x="16" y="17" width="328" height="269"/>
<beginningViews>
<textField verticalHuggingPriority="750" fixedFrame="YES" preferredMaxLayoutWidth="328" translatesAutoresizingMaskIntoConstraints="NO" id="hMJ-Mo-xOM">
<rect key="frame" x="-2" y="227" width="332" height="42"/>
<stackView distribution="fill" orientation="vertical" alignment="leading" horizontalStackHuggingPriority="250" verticalStackHuggingPriority="250" horizontalHuggingPriority="249" translatesAutoresizingMaskIntoConstraints="NO" id="j52-9L-k7c">
<rect key="frame" x="16" y="17" width="345" height="353"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="hMJ-Mo-xOM">
<rect key="frame" x="-2" y="311" width="349" height="42"/>
<textFieldCell key="cell" controlSize="small" id="H37-ku-aTc">
<font key="font" metaFont="smallSystem"/>
<string key="title">Autotype might not work properly. Some issues where found that prevent Autotype or Global Autotype to work. Please run the Autotype Doctor to fix those issues.</string>
@@ -46,8 +47,8 @@
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="jai-b6-Qv4">
<rect key="frame" x="-6" y="191" width="177" height="32"/>
<button horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="jai-b6-Qv4">
<rect key="frame" x="-7" y="276" width="171" height="32"/>
<buttonCell key="cell" type="push" title="Run Autotype Doctor…" bezelStyle="rounded" alignment="center" borderStyle="border" inset="2" id="NP0-R3-m6n">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
@@ -56,26 +57,26 @@
<action selector="runAutotypeDoctor:" target="-2" id="u2q-ab-rQY"/>
</connections>
</button>
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="tik-Ar-FJg">
<rect key="frame" x="-2" y="174" width="162" height="18"/>
<button horizontalHuggingPriority="249" translatesAutoresizingMaskIntoConstraints="NO" id="tik-Ar-FJg">
<rect key="frame" x="-2" y="258" width="347" height="18"/>
<buttonCell key="cell" type="check" title="Enable global Autotype" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="1qb-Rd-jYu">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
</button>
<stackView orientation="horizontal" alignment="centerY" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="d6A-Vb-CMt">
<rect key="frame" x="0.0" y="146" width="328" height="22"/>
<beginningViews>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="buI-Wb-o3V">
<rect key="frame" x="-2" y="3" width="57" height="17"/>
<stackView distribution="fill" orientation="horizontal" alignment="centerY" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" translatesAutoresizingMaskIntoConstraints="NO" id="d6A-Vb-CMt">
<rect key="frame" x="0.0" y="230" width="281" height="21"/>
<subviews>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="buI-Wb-o3V">
<rect key="frame" x="-2" y="3" width="57" height="16"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Shortcut" id="6oN-CH-T0O">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Kvg-he-3c8" customClass="DDHotKeyTextField">
<rect key="frame" x="61" y="0.0" width="136" height="22"/>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Kvg-he-3c8" customClass="DDHotKeyTextField">
<rect key="frame" x="61" y="0.0" width="89" height="21"/>
<constraints>
<constraint firstAttribute="width" constant="89" id="Mia-b8-HCZ"/>
</constraints>
@@ -85,15 +86,15 @@
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="f5q-EW-RHf">
<rect key="frame" x="203" y="4" width="127" height="14"/>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="f5q-EW-RHf">
<rect key="frame" x="156" y="4" width="127" height="14"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Shortcut is missing Key" id="Lxp-wI-yQy">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="disabledControlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</beginningViews>
</subviews>
<visibilityPriorities>
<integer value="1000"/>
<integer value="1000"/>
@@ -105,50 +106,66 @@
<real value="3.4028234663852886e+38"/>
</customSpacing>
</stackView>
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="DAX-V8-Say">
<rect key="frame" x="-2" y="122" width="208" height="18"/>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="uZQ-Gd-hfu">
<rect key="frame" x="-2" y="205" width="347" height="18"/>
<buttonCell key="cell" type="check" title="Always show confirmation before executing Autotype" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="rrU-70-Ara">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
</button>
<textField horizontalHuggingPriority="249" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="cUt-aB-oib">
<rect key="frame" x="-2" y="156" width="349" height="42"/>
<textFieldCell key="cell" controlSize="small" selectable="YES" id="VjU-Hz-cu4">
<font key="font" metaFont="smallSystem"/>
<string key="title">If enabled, a dialog will show up before Autotype is executed even if only a single match was found to prevent accidental input and wrong matches</string>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button horizontalHuggingPriority="249" translatesAutoresizingMaskIntoConstraints="NO" id="DAX-V8-Say">
<rect key="frame" x="-2" y="131" width="347" height="18"/>
<buttonCell key="cell" type="check" title="Include Entry Title for matches" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="tmL-dT-D0G">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
</button>
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8Wz-lo-AXG">
<rect key="frame" x="-2" y="100" width="206" height="18"/>
<button horizontalHuggingPriority="249" translatesAutoresizingMaskIntoConstraints="NO" id="8Wz-lo-AXG">
<rect key="frame" x="-2" y="107" width="347" height="18"/>
<buttonCell key="cell" type="check" title="Include Entry URL for matches" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="TzR-00-Vp3">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
</button>
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="TiO-ah-BlR">
<rect key="frame" x="-2" y="78" width="239" height="18"/>
<button horizontalHuggingPriority="249" translatesAutoresizingMaskIntoConstraints="NO" id="TiO-ah-BlR">
<rect key="frame" x="-2" y="83" width="347" height="18"/>
<buttonCell key="cell" type="check" title="Include Entry URL Host for matches" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="B1D-j9-L8x">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
</button>
<button fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="9MH-jx-GpG">
<rect key="frame" x="-2" y="56" width="210" height="18"/>
<button horizontalHuggingPriority="249" translatesAutoresizingMaskIntoConstraints="NO" id="9MH-jx-GpG">
<rect key="frame" x="-2" y="59" width="347" height="18"/>
<buttonCell key="cell" type="check" title="Include Entry Tags for matches" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="rbu-G7-MT8">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
</button>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="VK8-z4-2ci">
<rect key="frame" x="-2" y="34" width="122" height="18"/>
<button horizontalHuggingPriority="249" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="VK8-z4-2ci">
<rect key="frame" x="-2" y="35" width="347" height="18"/>
<buttonCell key="cell" type="check" title="Interpret ⌃ as ⌘" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="QfO-yG-l3F">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
</button>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" fixedFrame="YES" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="wbP-A9-jpw">
<rect key="frame" x="-2" y="0.0" width="332" height="28"/>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="wbP-A9-jpw">
<rect key="frame" x="-2" y="0.0" width="349" height="28"/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" title="If enabled, every {CONTROL} command will be sent as ⌘. Only disable this if you are sure you need to." id="QRy-CY-ENC">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</beginningViews>
</subviews>
<visibilityPriorities>
<integer value="1000"/>
<integer value="1000"/>
@@ -160,6 +177,8 @@
<integer value="1000"/>
<integer value="1000"/>
<integer value="1000"/>
<integer value="1000"/>
<integer value="1000"/>
</visibilityPriorities>
<customSpacing>
<real value="3.4028234663852886e+38"/>
@@ -172,6 +191,8 @@
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
</customSpacing>
</stackView>
</subviews>
@@ -184,20 +205,20 @@
</constraints>
</box>
<box autoresizesSubviews="NO" verticalHuggingPriority="500" borderType="line" title="Preview" translatesAutoresizingMaskIntoConstraints="NO" id="VVs-b5-cX9">
<rect key="frame" x="17" y="16" width="366" height="95"/>
<rect key="frame" x="17" y="145" width="383" height="97"/>
<view key="contentView" id="ww4-uR-8gP">
<rect key="frame" x="3" y="3" width="360" height="77"/>
<rect key="frame" x="3" y="3" width="377" height="79"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<button translatesAutoresizingMaskIntoConstraints="NO" id="LNw-5t-TS4">
<rect key="frame" x="14" y="51" width="178" height="18"/>
<rect key="frame" x="14" y="52" width="182" height="18"/>
<buttonCell key="cell" type="check" title="Enable Quicklook Preview" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="ERs-ct-Eyx">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
</button>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="V6l-R9-hIj">
<rect key="frame" x="14" y="17" width="332" height="28"/>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="V6l-R9-hIj">
<rect key="frame" x="14" y="17" width="349" height="28"/>
<textFieldCell key="cell" controlSize="small" sendsActionOnEndEditing="YES" title="If enabled attached files will be copied to a temporary location for preview and deleted after the preview is closed." id="WmI-IB-Aso">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@@ -218,18 +239,57 @@
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="V6l-R9-hIj" secondAttribute="trailing" constant="16" id="ivY-UD-QFJ"/>
</constraints>
</box>
<box title="Keychain" translatesAutoresizingMaskIntoConstraints="NO" id="ChZ-ku-FOP">
<rect key="frame" x="17" y="16" width="383" height="125"/>
<view key="contentView" id="ocY-lR-P2Z">
<rect key="frame" x="3" y="3" width="377" height="107"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="u5z-ST-gTK">
<rect key="frame" x="9" y="60" width="154" height="32"/>
<buttonCell key="cell" type="push" title="Renew TouchID Key" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="b4n-g4-CtW">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="RenewTouchIdKey:" target="-2" id="dl7-WD-Abu"/>
</connections>
</button>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="9kv-ns-mQx">
<rect key="frame" x="14" y="16" width="349" height="42"/>
<textFieldCell key="cell" controlSize="small" sendsActionOnEndEditing="YES" id="LyC-Hd-ecK">
<font key="font" metaFont="smallSystem"/>
<string key="title">MacPass will no longer be able to unlock any Database with TouchID until it is successfully unlocked with the password and or keyfile.</string>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<constraints>
<constraint firstAttribute="bottom" secondItem="9kv-ns-mQx" secondAttribute="bottom" constant="16" id="INC-l7-zwP"/>
<constraint firstItem="u5z-ST-gTK" firstAttribute="leading" secondItem="ocY-lR-P2Z" secondAttribute="leading" constant="16" id="KDt-yM-fh3"/>
<constraint firstItem="9kv-ns-mQx" firstAttribute="top" secondItem="u5z-ST-gTK" secondAttribute="bottom" constant="9" id="RjN-pw-qLc"/>
<constraint firstItem="9kv-ns-mQx" firstAttribute="leading" secondItem="u5z-ST-gTK" secondAttribute="leading" id="X5L-Rj-Wky"/>
<constraint firstItem="u5z-ST-gTK" firstAttribute="top" secondItem="ocY-lR-P2Z" secondAttribute="top" constant="20" symbolic="YES" id="guH-ws-dzX"/>
<constraint firstAttribute="trailing" secondItem="9kv-ns-mQx" secondAttribute="trailing" constant="16" id="icu-An-dNK"/>
<constraint firstAttribute="trailing" relation="lessThanOrEqual" secondItem="u5z-ST-gTK" secondAttribute="trailing" priority="240" constant="16" id="rni-sA-a7w"/>
</constraints>
</view>
</box>
</subviews>
<constraints>
<constraint firstAttribute="width" constant="400" id="19"/>
<constraint firstItem="ChZ-ku-FOP" firstAttribute="trailing" secondItem="ww4-uR-8gP" secondAttribute="trailing" id="39G-i3-XQa"/>
<constraint firstItem="ChZ-ku-FOP" firstAttribute="top" secondItem="VVs-b5-cX9" secondAttribute="bottom" constant="8" symbolic="YES" id="3ub-U2-KCr"/>
<constraint firstItem="P9N-HM-wER" firstAttribute="top" secondItem="1" secondAttribute="top" constant="20" symbolic="YES" id="8fy-q5-VJy"/>
<constraint firstAttribute="bottom" secondItem="VVs-b5-cX9" secondAttribute="bottom" constant="20" symbolic="YES" id="TZB-qe-7eg"/>
<constraint firstItem="VVs-b5-cX9" firstAttribute="top" secondItem="P9N-HM-wER" secondAttribute="bottom" constant="8" id="VCX-JW-cBe"/>
<constraint firstItem="ChZ-ku-FOP" firstAttribute="leading" secondItem="ww4-uR-8gP" secondAttribute="leading" id="BQW-Zd-udd"/>
<constraint firstAttribute="bottom" secondItem="ChZ-ku-FOP" secondAttribute="bottom" constant="20" symbolic="YES" id="DBk-vZ-yOT"/>
<constraint firstItem="VVs-b5-cX9" firstAttribute="top" secondItem="P9N-HM-wER" secondAttribute="bottom" constant="8" symbolic="YES" id="VCX-JW-cBe"/>
<constraint firstItem="VVs-b5-cX9" firstAttribute="trailing" secondItem="P9N-HM-wER" secondAttribute="trailing" id="k9i-4T-WY0"/>
<constraint firstAttribute="trailing" secondItem="P9N-HM-wER" secondAttribute="trailing" constant="20" id="n5w-Cw-Bbt"/>
<constraint firstItem="P9N-HM-wER" firstAttribute="leading" secondItem="1" secondAttribute="leading" constant="20" id="ulV-xL-ldJ"/>
<constraint firstItem="VVs-b5-cX9" firstAttribute="leading" secondItem="P9N-HM-wER" secondAttribute="leading" id="z4a-9C-78h"/>
</constraints>
<point key="canvasLocation" x="-558" y="-1123"/>
<point key="canvasLocation" x="-1204.5" y="-1287.5"/>
</customView>
</objects>
</document>

View File

@@ -1,17 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="15705" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15705"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17701"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="MPPasswordEditWindowController">
<connections>
<outlet property="changePasswordButton" destination="68" id="85"/>
<outlet property="errorTextField" destination="12" id="79"/>
<outlet property="hasPasswordSwitchButton" destination="yKc-I9-uzv" id="aUH-R4-WwP"/>
<outlet property="keyErrorTextField" destination="ibK-Px-Fvt" id="l7h-qa-idf"/>
<outlet property="keyfilePathControl" destination="4" id="63"/>
<outlet property="passwordErrorTextField" destination="12" id="79"/>
<outlet property="passwordRepeatTextField" destination="11" id="62"/>
<outlet property="passwordTextField" destination="9" id="61"/>
<outlet property="togglePasswordButton" destination="7" id="64"/>
@@ -23,99 +24,13 @@
<window title="Change Password" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="1">
<windowStyleMask key="styleMask" titled="YES" closable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="196" y="240" width="403" height="219"/>
<rect key="contentRect" x="1090" y="652" width="369" height="164"/>
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
<view key="contentView" id="2">
<rect key="frame" x="0.0" y="0.0" width="403" height="210"/>
<autoresizingMask key="autoresizingMask"/>
<view key="contentView" verticalHuggingPriority="251" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="2">
<rect key="frame" x="0.0" y="0.0" width="363" height="220"/>
<subviews>
<pathControl verticalHuggingPriority="750" allowsExpansionToolTips="YES" translatesAutoresizingMaskIntoConstraints="NO" id="4" customClass="MPPathControl">
<rect key="frame" x="105" y="87" width="242" height="25"/>
<pathCell key="cell" selectable="YES" editable="YES" alignment="left" pathStyle="popUp" id="23" customClass="MPPathCell">
<font key="font" metaFont="system"/>
</pathCell>
</pathControl>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="5">
<rect key="frame" x="53" y="91" width="49" height="16"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Keyfile:" id="22">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="6">
<rect key="frame" x="108" y="60" width="236" height="23"/>
<buttonCell key="cell" type="roundTextured" title="Generate Keyfile" bezelStyle="texturedRounded" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="21">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="generateKey:" target="-2" id="66"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="7">
<rect key="frame" x="352" y="145" width="31" height="23"/>
<constraints>
<constraint firstAttribute="width" constant="31" id="59"/>
</constraints>
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="NSQuickLookTemplate" imagePosition="only" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="20">
<behavior key="behavior" pushIn="YES" changeContents="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="8">
<rect key="frame" x="352" y="89" width="31" height="23"/>
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="NSStopProgressTemplate" imagePosition="only" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="19">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="clearKey:" target="-2" id="65"/>
</connections>
</button>
<secureTextField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="9" customClass="HNHUISecureTextField">
<rect key="frame" x="108" y="148" width="236" height="20"/>
<constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="200" id="Gin-yR-DMk"/>
</constraints>
<secureTextFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" placeholderString="Enter Password" drawsBackground="YES" usesSingleLineMode="YES" id="18">
<font key="font" size="13" name="Menlo-Regular"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
<allowedInputSourceLocales>
<string>NSAllRomanInputSourcesLocaleIdentifier</string>
</allowedInputSourceLocales>
</secureTextFieldCell>
</secureTextField>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="10">
<rect key="frame" x="51" y="121" width="51" height="16"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Repeat:" id="16">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<secureTextField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="11" customClass="HNHUISecureTextField">
<rect key="frame" x="108" y="118" width="236" height="20"/>
<secureTextFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" placeholderString="Repeat Password" drawsBackground="YES" usesSingleLineMode="YES" id="15">
<font key="font" size="13" name="Menlo-Regular"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
<allowedInputSourceLocales>
<string>NSAllRomanInputSourcesLocaleIdentifier</string>
</allowedInputSourceLocales>
</secureTextFieldCell>
</secureTextField>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="12">
<rect key="frame" x="161" y="176" width="131" height="14"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Mismatching Passwords" id="14">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" red="1" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="68">
<rect key="frame" x="240" y="13" width="149" height="32"/>
<rect key="frame" x="200" y="13" width="149" height="32"/>
<buttonCell key="cell" type="push" title="Change Password" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="69">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
@@ -125,7 +40,7 @@
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="72">
<rect key="frame" x="158" y="13" width="82" height="32"/>
<rect key="frame" x="118" y="13" width="82" height="32"/>
<buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="73">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
@@ -137,59 +52,168 @@ Gw
<action selector="cancel:" target="-2" id="84"/>
</connections>
</button>
<button horizontalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="yKc-I9-uzv">
<rect key="frame" x="18" y="150" width="84" height="18"/>
<buttonCell key="cell" type="check" title="Password:" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="OQz-DA-SoY">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
</button>
<gridView horizontalHuggingPriority="251" verticalHuggingPriority="750" xPlacement="leading" yPlacement="bottom" rowAlignment="none" translatesAutoresizingMaskIntoConstraints="NO" id="0Iv-td-ACj">
<rect key="frame" x="20" y="61" width="323" height="139"/>
<rows>
<gridRow id="Ljm-xA-9NW"/>
<gridRow id="Dv9-ND-6rX"/>
<gridRow id="mNb-JP-3YX"/>
<gridRow id="vQK-bD-mNH"/>
<gridRow id="DIe-Hz-bd0"/>
<gridRow id="TQt-iq-lMT"/>
</rows>
<columns>
<gridColumn xPlacement="trailing" id="uaf-ph-2zN"/>
<gridColumn xPlacement="fill" id="7oF-Xq-5de"/>
<gridColumn xPlacement="fill" id="clB-mU-Eba"/>
</columns>
<gridCells>
<gridCell row="Ljm-xA-9NW" column="uaf-ph-2zN" id="1U3-Im-v9n"/>
<gridCell row="Ljm-xA-9NW" column="7oF-Xq-5de" id="2bp-dG-V6t">
<textField key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="12">
<rect key="frame" x="84" y="125" width="204" height="14"/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" title="PASSWORD_ERROR" id="14">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" red="1" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</gridCell>
<gridCell row="Ljm-xA-9NW" column="clB-mU-Eba" id="blk-az-oHS"/>
<gridCell row="Dv9-ND-6rX" column="uaf-ph-2zN" id="JUU-XQ-60P">
<button key="contentView" horizontalHuggingPriority="252" translatesAutoresizingMaskIntoConstraints="NO" id="yKc-I9-uzv">
<rect key="frame" x="-2" y="97" width="84" height="24"/>
<buttonCell key="cell" type="check" title="Password:" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="OQz-DA-SoY">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
</button>
</gridCell>
<gridCell row="Dv9-ND-6rX" column="7oF-Xq-5de" id="cw2-er-epO">
<secureTextField key="contentView" horizontalHuggingPriority="253" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="9" customClass="HNHUISecureTextField">
<rect key="frame" x="86" y="99" width="200" height="20"/>
<constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="200" id="gTV-5A-Fyo"/>
</constraints>
<secureTextFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" placeholderString="Enter Password" drawsBackground="YES" usesSingleLineMode="YES" id="18">
<font key="font" size="13" name="Menlo-Regular"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
<allowedInputSourceLocales>
<string>NSAllRomanInputSourcesLocaleIdentifier</string>
</allowedInputSourceLocales>
</secureTextFieldCell>
</secureTextField>
</gridCell>
<gridCell row="Dv9-ND-6rX" column="clB-mU-Eba" id="ykQ-xV-MfJ"/>
<gridCell row="mNb-JP-3YX" column="uaf-ph-2zN" id="DTm-fw-duK">
<textField key="contentView" horizontalHuggingPriority="252" verticalHuggingPriority="751" translatesAutoresizingMaskIntoConstraints="NO" id="10">
<rect key="frame" x="31" y="73" width="51" height="16"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Repeat:" id="16">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</gridCell>
<gridCell row="mNb-JP-3YX" column="7oF-Xq-5de" id="OBv-b8-DJs">
<secureTextField key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="11" customClass="HNHUISecureTextField">
<rect key="frame" x="86" y="73" width="200" height="20"/>
<secureTextFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" placeholderString="Repeat Password" drawsBackground="YES" usesSingleLineMode="YES" id="15">
<font key="font" size="13" name="Menlo-Regular"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
<allowedInputSourceLocales>
<string>NSAllRomanInputSourcesLocaleIdentifier</string>
</allowedInputSourceLocales>
</secureTextFieldCell>
</secureTextField>
</gridCell>
<gridCell row="mNb-JP-3YX" column="clB-mU-Eba" id="erv-Ur-nvi">
<button key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="7">
<rect key="frame" x="292" y="72" width="31" height="21"/>
<constraints>
<constraint firstAttribute="width" constant="31" id="59"/>
</constraints>
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="NSQuickLookTemplate" imagePosition="only" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="20">
<behavior key="behavior" pushIn="YES" changeContents="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
</button>
</gridCell>
<gridCell row="vQK-bD-mNH" column="uaf-ph-2zN" id="5U0-j9-rrv"/>
<gridCell row="vQK-bD-mNH" column="7oF-Xq-5de" id="8JE-Wh-Sad">
<textField key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ibK-Px-Fvt">
<rect key="frame" x="84" y="53" width="204" height="14"/>
<textFieldCell key="cell" sendsActionOnEndEditing="YES" title="KEY_ERROR" id="EOD-dE-TFa">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" red="1" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</gridCell>
<gridCell row="vQK-bD-mNH" column="clB-mU-Eba" id="fyu-1E-DpO"/>
<gridCell row="DIe-Hz-bd0" column="uaf-ph-2zN" id="Pjk-hs-Pb5">
<textField key="contentView" horizontalHuggingPriority="252" verticalHuggingPriority="749" translatesAutoresizingMaskIntoConstraints="NO" id="5">
<rect key="frame" x="33" y="28" width="49" height="19"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Keyfile:" id="22">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</gridCell>
<gridCell row="DIe-Hz-bd0" column="7oF-Xq-5de" id="o9J-f7-adq">
<pathControl key="contentView" verticalHuggingPriority="750" allowsExpansionToolTips="YES" translatesAutoresizingMaskIntoConstraints="NO" id="4" customClass="MPPathControl">
<rect key="frame" x="83" y="24" width="206" height="25"/>
<pathCell key="cell" selectable="YES" editable="YES" alignment="left" pathStyle="popUp" id="23" customClass="MPPathCell">
<font key="font" metaFont="system"/>
</pathCell>
</pathControl>
</gridCell>
<gridCell row="DIe-Hz-bd0" column="clB-mU-Eba" id="miK-hQ-pkN">
<button key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="8">
<rect key="frame" x="292" y="27" width="31" height="20"/>
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="NSStopProgressTemplate" imagePosition="only" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="19">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="clearKey:" target="-2" id="65"/>
</connections>
</button>
</gridCell>
<gridCell row="TQt-iq-lMT" column="uaf-ph-2zN" id="nAI-ge-Vjb"/>
<gridCell row="TQt-iq-lMT" column="7oF-Xq-5de" id="dT5-pB-M7d">
<button key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="6">
<rect key="frame" x="86" y="-1" width="200" height="23"/>
<buttonCell key="cell" type="roundTextured" title="Generate Keyfile" bezelStyle="texturedRounded" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="21">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="generateKey:" target="-2" id="66"/>
</connections>
</button>
</gridCell>
<gridCell row="TQt-iq-lMT" column="clB-mU-Eba" id="zle-AC-ZGd"/>
</gridCells>
</gridView>
</subviews>
<constraints>
<constraint firstItem="9" firstAttribute="top" secondItem="12" secondAttribute="bottom" constant="8" symbolic="YES" id="26"/>
<constraint firstItem="4" firstAttribute="leading" secondItem="5" secondAttribute="trailing" constant="8" symbolic="YES" id="27"/>
<constraint firstItem="10" firstAttribute="baseline" secondItem="11" secondAttribute="baseline" id="29"/>
<constraint firstItem="7" firstAttribute="leading" secondItem="9" secondAttribute="trailing" constant="8" symbolic="YES" id="30"/>
<constraint firstItem="4" firstAttribute="top" secondItem="11" secondAttribute="bottom" constant="8" symbolic="YES" id="35"/>
<constraint firstItem="7" firstAttribute="top" secondItem="9" secondAttribute="top" id="36"/>
<constraint firstItem="11" firstAttribute="leading" secondItem="10" secondAttribute="trailing" constant="8" symbolic="YES" id="37"/>
<constraint firstItem="6" firstAttribute="top" secondItem="4" secondAttribute="bottom" constant="8" symbolic="YES" id="39"/>
<constraint firstItem="12" firstAttribute="centerX" secondItem="9" secondAttribute="centerX" id="40"/>
<constraint firstItem="8" firstAttribute="centerY" secondItem="4" secondAttribute="centerY" id="41"/>
<constraint firstItem="4" firstAttribute="bottom" secondItem="5" secondAttribute="bottom" id="43"/>
<constraint firstItem="12" firstAttribute="top" secondItem="2" secondAttribute="top" constant="20" symbolic="YES" id="53"/>
<constraint firstAttribute="trailing" secondItem="8" secondAttribute="trailing" constant="20" symbolic="YES" id="56"/>
<constraint firstAttribute="trailing" secondItem="7" secondAttribute="trailing" constant="20" symbolic="YES" id="57"/>
<constraint firstAttribute="trailing" secondItem="68" secondAttribute="trailing" constant="20" symbolic="YES" id="71"/>
<constraint firstItem="68" firstAttribute="leading" secondItem="72" secondAttribute="trailing" constant="12" symbolic="YES" id="75"/>
<constraint firstItem="72" firstAttribute="top" secondItem="6" secondAttribute="bottom" constant="20" symbolic="YES" id="76"/>
<constraint firstAttribute="bottom" secondItem="72" secondAttribute="bottom" constant="20" symbolic="YES" id="77"/>
<constraint firstAttribute="bottom" secondItem="68" secondAttribute="bottom" constant="20" symbolic="YES" id="78"/>
<constraint firstItem="5" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="2" secondAttribute="leading" constant="20" symbolic="YES" id="4Yq-mp-X3O"/>
<constraint firstItem="4" firstAttribute="width" secondItem="11" secondAttribute="width" id="55p-Rc-8jw"/>
<constraint firstItem="0Iv-td-ACj" firstAttribute="leading" secondItem="2" secondAttribute="leading" constant="20" symbolic="YES" id="4Gf-qW-X3R"/>
<constraint firstItem="72" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="2" secondAttribute="leading" constant="20" symbolic="YES" id="5JM-Ve-z5Y"/>
<constraint firstItem="8" firstAttribute="leading" secondItem="4" secondAttribute="trailing" constant="8" id="7GY-2X-nJn"/>
<constraint firstItem="4" firstAttribute="leading" secondItem="5" secondAttribute="trailing" constant="8" id="7eR-m5-mhQ"/>
<constraint firstItem="9" firstAttribute="baseline" secondItem="yKc-I9-uzv" secondAttribute="baseline" id="DrZ-BA-xPv"/>
<constraint firstItem="7" firstAttribute="leading" secondItem="9" secondAttribute="trailing" constant="8" id="IqJ-u6-6jk"/>
<constraint firstItem="yKc-I9-uzv" firstAttribute="leading" secondItem="2" secondAttribute="leading" constant="20" symbolic="YES" id="OdM-OO-kNS"/>
<constraint firstItem="7" firstAttribute="leading" secondItem="9" secondAttribute="trailing" constant="8" symbolic="YES" id="PnG-bb-nYQ"/>
<constraint firstItem="11" firstAttribute="top" secondItem="9" secondAttribute="bottom" constant="10" symbolic="YES" id="Qe9-z3-Wa6"/>
<constraint firstItem="yKc-I9-uzv" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="2" secondAttribute="leading" constant="20" symbolic="YES" id="R8d-VG-2we"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="6" secondAttribute="trailing" constant="20" symbolic="YES" id="TUn-PZ-fb5"/>
<constraint firstItem="10" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="2" secondAttribute="leading" constant="20" symbolic="YES" id="UHJ-Fx-Kkf"/>
<constraint firstItem="6" firstAttribute="width" secondItem="11" secondAttribute="width" id="V37-mo-ah1"/>
<constraint firstItem="9" firstAttribute="leading" secondItem="yKc-I9-uzv" secondAttribute="trailing" constant="8" symbolic="YES" id="f8B-Dm-rGD"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="12" secondAttribute="trailing" constant="20" symbolic="YES" id="hmt-qe-o3D"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="11" secondAttribute="trailing" constant="20" symbolic="YES" id="nDO-Oh-tGz"/>
<constraint firstItem="6" firstAttribute="leading" secondItem="4" secondAttribute="leading" id="tie-Hu-X1C"/>
<constraint firstItem="12" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="2" secondAttribute="leading" constant="20" symbolic="YES" id="ukY-Gg-KY2"/>
<constraint firstItem="11" firstAttribute="width" secondItem="9" secondAttribute="width" id="wEk-Sj-XCb"/>
<constraint firstItem="6" firstAttribute="leading" secondItem="11" secondAttribute="leading" id="xV3-et-ECG"/>
<constraint firstItem="6" firstAttribute="leading" secondItem="9" secondAttribute="leading" id="zeJ-6i-fY3"/>
<constraint firstItem="0Iv-td-ACj" firstAttribute="top" secondItem="2" secondAttribute="top" constant="20" symbolic="YES" id="FVY-mT-b2G"/>
<constraint firstAttribute="width" relation="lessThanOrEqual" constant="400" id="mhj-K7-dob"/>
<constraint firstAttribute="trailing" secondItem="0Iv-td-ACj" secondAttribute="trailing" constant="20" symbolic="YES" id="q2z-sU-YCn"/>
<constraint firstItem="68" firstAttribute="top" secondItem="0Iv-td-ACj" secondAttribute="bottom" constant="20" symbolic="YES" id="s84-KY-RXX"/>
</constraints>
</view>
<point key="canvasLocation" x="-8" y="-14"/>
<point key="canvasLocation" x="-295" y="-412"/>
</window>
</objects>
<resources>

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="15705" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="18122" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15705"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="18122"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@@ -16,6 +16,8 @@
<outlet property="messageInfoTextField" destination="268" id="ahE-sq-QzR"/>
<outlet property="passwordTextField" destination="338" id="495"/>
<outlet property="togglePasswordButton" destination="408" id="493"/>
<outlet property="touchIdButton" destination="mQA-C0-JyU" id="fM3-PG-1OB"/>
<outlet property="touchIdEnabledButton" destination="Hs8-Tc-ezo" id="9Go-LQ-mSw"/>
<outlet property="unlockButton" destination="2" id="ZRr-Ui-ExP"/>
<outlet property="view" destination="1" id="143"/>
</connections>
@@ -25,19 +27,6 @@
<customView horizontalCompressionResistancePriority="751" translatesAutoresizingMaskIntoConstraints="NO" id="1">
<rect key="frame" x="0.0" y="0.0" width="508" height="526"/>
<subviews>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="2">
<rect key="frame" x="310" y="168" width="83" height="32"/>
<buttonCell key="cell" type="push" title="Unlock" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="3">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<string key="keyEquivalent" base64-UTF8="YES">
DQ
</string>
</buttonCell>
<connections>
<action selector="_submit:" target="-2" id="KZN-ap-nDc"/>
</connections>
</button>
<textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="17">
<rect key="frame" x="108" y="226" width="45" height="16"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Keyfile" id="18">
@@ -53,7 +42,7 @@ DQ
</pathCell>
</pathControl>
<imageView translatesAutoresizingMaskIntoConstraints="NO" id="262">
<rect key="frame" x="230" y="305" width="48" height="48"/>
<rect key="frame" x="230" y="332" width="48" height="48"/>
<constraints>
<constraint firstAttribute="height" constant="48" id="273"/>
<constraint firstAttribute="width" constant="48" id="456"/>
@@ -61,7 +50,7 @@ DQ
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyUpOrDown" image="02_MessageBoxWarningTemplate" id="263"/>
</imageView>
<textField verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="268">
<rect key="frame" x="199" y="281" width="110" height="16"/>
<rect key="frame" x="199" y="308" width="110" height="16"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Wrong password!" id="269">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@@ -73,7 +62,7 @@ DQ
<constraints>
<constraint firstAttribute="width" constant="191" id="389"/>
</constraints>
<secureTextFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" placeholderString="Enter Password" drawsBackground="YES" usesSingleLineMode="YES" id="339">
<secureTextFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" placeholderString="Enter Password" drawsBackground="YES" usesSingleLineMode="YES" id="339" customClass="HNHUISecureTextFieldCell">
<font key="font" size="13" name="Menlo-Regular"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
@@ -86,14 +75,14 @@ DQ
</connections>
</secureTextField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="408">
<rect key="frame" x="358" y="250" width="29" height="23"/>
<rect key="frame" x="357" y="251" width="32" height="23"/>
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="NSQuickLookTemplate" imagePosition="only" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="409">
<behavior key="behavior" pushIn="YES" changeContents="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="486">
<rect key="frame" x="358" y="220" width="29" height="23"/>
<rect key="frame" x="357" y="221" width="32" height="23"/>
<buttonCell key="cell" type="roundTextured" bezelStyle="texturedRounded" image="NSStopProgressTemplate" imagePosition="only" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="487">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
@@ -103,40 +92,86 @@ DQ
</connections>
</button>
<button translatesAutoresizingMaskIntoConstraints="NO" id="d8O-Ha-rrS">
<rect key="frame" x="72" y="254" width="81" height="18"/>
<rect key="frame" x="66" y="254" width="85" height="18"/>
<buttonCell key="cell" type="check" title="Password" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="IU9-5u-jn9">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="2pb-ZG-spA">
<rect key="frame" x="228" y="168" width="82" height="32"/>
<buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="erj-mR-UyO">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<string key="keyEquivalent" base64-UTF8="YES">
<stackView distribution="fill" orientation="horizontal" alignment="top" spacing="12" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="tck-n8-s0U" userLabel="SubmitButtonContainer">
<rect key="frame" x="164" y="176" width="224" height="20"/>
<subviews>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="2pb-ZG-spA">
<rect key="frame" x="-7" y="-7" width="76" height="32"/>
<buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="erj-mR-UyO">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<string key="keyEquivalent" base64-UTF8="YES">
Gw
</string>
</buttonCell>
<connections>
<action selector="_submit:" target="-2" id="aVF-1d-1Hq"/>
</connections>
</button>
</buttonCell>
<connections>
<action selector="_submit:" target="-2" id="aVF-1d-1Hq"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="mQA-C0-JyU">
<rect key="frame" x="67" y="-7" width="88" height="32"/>
<buttonCell key="cell" type="push" title="Touch ID" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="W9h-1u-9kq">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="unlockWithTouchID:" target="-2" id="1yL-6V-t8q"/>
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="2">
<rect key="frame" x="153" y="-7" width="78" height="32"/>
<buttonCell key="cell" type="push" title="Unlock" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="3">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<string key="keyEquivalent" base64-UTF8="YES">
DQ
</string>
</buttonCell>
<connections>
<action selector="_submit:" target="-2" id="KZN-ap-nDc"/>
</connections>
</button>
</subviews>
<visibilityPriorities>
<integer value="1000"/>
<integer value="1000"/>
<integer value="1000"/>
</visibilityPriorities>
<customSpacing>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
</customSpacing>
</stackView>
<textField hidden="YES" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="txI-yI-5nE">
<rect key="frame" x="157" y="204" width="195" height="14"/>
<textFieldCell key="cell" selectable="YES" title="key_file_warnig" id="f6J-5f-ZvP">
<font key="font" metaFont="smallSystem"/>
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Hs8-Tc-ezo">
<rect key="frame" x="66" y="287" width="76" height="18"/>
<buttonCell key="cell" type="check" title="TouchID" bezelStyle="regularSquare" imagePosition="left" allowsMixedState="YES" inset="2" id="h3C-Z4-x7N">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="touchIdEnabledChanged:" target="-2" id="3pR-xA-wbI"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="2" secondAttribute="bottom" constant="20" symbolic="YES" id="122"/>
<constraint firstItem="262" firstAttribute="top" relation="greaterThanOrEqual" secondItem="1" secondAttribute="top" constant="20" symbolic="YES" id="276"/>
<constraint firstAttribute="centerX" secondItem="262" secondAttribute="centerX" id="286"/>
<constraint firstAttribute="centerY" secondItem="338" secondAttribute="centerY" id="386"/>
<constraint firstItem="338" firstAttribute="top" secondItem="268" secondAttribute="bottom" constant="8" symbolic="YES" id="400"/>
<constraint firstItem="268" firstAttribute="top" secondItem="262" secondAttribute="bottom" constant="8" symbolic="YES" id="402"/>
<constraint firstItem="408" firstAttribute="top" secondItem="338" secondAttribute="top" id="411"/>
<constraint firstItem="268" firstAttribute="centerX" secondItem="338" secondAttribute="centerX" id="447"/>
@@ -150,26 +185,28 @@ Gw
<constraint firstItem="486" firstAttribute="leading" secondItem="241" secondAttribute="trailing" constant="8" symbolic="YES" id="489"/>
<constraint firstItem="486" firstAttribute="leading" secondItem="408" secondAttribute="leading" id="490"/>
<constraint firstItem="408" firstAttribute="trailing" secondItem="486" secondAttribute="trailing" id="492"/>
<constraint firstItem="2" firstAttribute="trailing" secondItem="486" secondAttribute="trailing" id="496"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="Hs8-Tc-ezo" secondAttribute="trailing" constant="20" symbolic="YES" id="4Zq-48-2fD"/>
<constraint firstItem="tck-n8-s0U" firstAttribute="top" secondItem="txI-yI-5nE" secondAttribute="bottom" constant="8" id="6tz-an-3SW"/>
<constraint firstItem="408" firstAttribute="leading" secondItem="338" secondAttribute="trailing" constant="8" symbolic="YES" id="7qE-8F-QgB"/>
<constraint firstItem="2pb-ZG-spA" firstAttribute="baseline" secondItem="2" secondAttribute="baseline" id="9nK-MH-Ozs"/>
<constraint firstItem="txI-yI-5nE" firstAttribute="trailing" secondItem="241" secondAttribute="trailing" id="AVL-HO-SMq"/>
<constraint firstItem="17" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="1" secondAttribute="leading" constant="20" symbolic="YES" id="EOa-K4-v7J"/>
<constraint firstItem="338" firstAttribute="leading" secondItem="d8O-Ha-rrS" secondAttribute="trailing" constant="8" symbolic="YES" id="KYs-Ia-SVl"/>
<constraint firstItem="2pb-ZG-spA" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="1" secondAttribute="leading" constant="20" symbolic="YES" id="SUS-76-os4"/>
<constraint firstItem="2" firstAttribute="top" secondItem="txI-yI-5nE" secondAttribute="bottom" constant="8" symbolic="YES" id="jJs-hc-O2O"/>
<constraint firstItem="Hs8-Tc-ezo" firstAttribute="leading" secondItem="d8O-Ha-rrS" secondAttribute="leading" id="MO7-cs-9KQ"/>
<constraint firstItem="d8O-Ha-rrS" firstAttribute="top" secondItem="Hs8-Tc-ezo" secondAttribute="bottom" constant="17" id="Rhp-Gn-AaI"/>
<constraint firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="tck-n8-s0U" secondAttribute="bottom" constant="20" symbolic="YES" id="Sny-FR-cY1"/>
<constraint firstItem="tck-n8-s0U" firstAttribute="trailing" secondItem="486" secondAttribute="trailing" id="UtJ-18-p5u"/>
<constraint firstItem="Hs8-Tc-ezo" firstAttribute="firstBaseline" secondItem="268" secondAttribute="firstBaseline" constant="20" id="e94-Kz-Ohn"/>
<constraint firstItem="d8O-Ha-rrS" firstAttribute="centerY" secondItem="338" secondAttribute="centerY" id="kgB-jV-OGy"/>
<constraint firstItem="txI-yI-5nE" firstAttribute="top" secondItem="241" secondAttribute="bottom" constant="8" symbolic="YES" id="lfg-eB-T2O"/>
<constraint firstItem="txI-yI-5nE" firstAttribute="leading" secondItem="241" secondAttribute="leading" id="nGY-6Q-Vwy"/>
<constraint firstItem="d8O-Ha-rrS" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="1" secondAttribute="leading" constant="20" symbolic="YES" id="vxq-YP-UhR"/>
<constraint firstItem="2" firstAttribute="leading" secondItem="2pb-ZG-spA" secondAttribute="trailing" constant="12" id="ytJ-5Z-5rT"/>
</constraints>
<point key="canvasLocation" x="-127" y="-46"/>
</customView>
</objects>
<resources>
<image name="02_MessageBoxWarningTemplate" width="16" height="16"/>
<image name="NSQuickLookTemplate" width="19" height="12"/>
<image name="NSStopProgressTemplate" width="11" height="11"/>
<image name="NSQuickLookTemplate" width="21" height="13"/>
<image name="NSStopProgressTemplate" width="14" height="13"/>
</resources>
</document>

View File

@@ -65,7 +65,7 @@
<font key="font" metaFont="system"/>
</buttonCell>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="aoG-FD-ds8">
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="aoG-FD-ds8">
<rect key="frame" x="18" y="388" width="571" height="28"/>
<textFieldCell key="cell" controlSize="small" sendsActionOnEndEditing="YES" id="2bX-8S-9XM">
<font key="font" metaFont="smallSystem"/>
@@ -155,7 +155,7 @@
</scroller>
</scrollView>
<segmentedControl verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="B9Q-hq-K4N">
<rect key="frame" x="19.5" y="19" width="71" height="23"/>
<rect key="frame" x="20" y="19" width="71" height="23"/>
<segmentedCell key="cell" borderStyle="border" alignment="left" style="texturedSquare" trackingMode="momentary" id="cj3-R6-g1E">
<font key="font" metaFont="system"/>
<segments>
@@ -168,7 +168,7 @@
</connections>
</segmentedControl>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="SNe-cc-CZs">
<rect key="frame" x="413.5" y="19" width="174" height="23"/>
<rect key="frame" x="413" y="19" width="174" height="23"/>
<buttonCell key="cell" type="roundTextured" title="Browse Available Plugins…" bezelStyle="texturedRounded" alignment="center" lineBreakMode="truncatingTail" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="sqO-8H-n1y">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
@@ -191,7 +191,7 @@
<font key="font" metaFont="system"/>
</buttonCell>
</button>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" setsMaxLayoutWidthAtFirstLayout="YES" translatesAutoresizingMaskIntoConstraints="NO" id="nrf-Hz-0vB">
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="nrf-Hz-0vB">
<rect key="frame" x="18" y="446" width="349" height="14"/>
<textFieldCell key="cell" controlSize="small" selectable="YES" title="If enabled, a remote connection is established to macpassapp.org" id="i3S-9b-Bpf">
<font key="font" metaFont="smallSystem"/>

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="16097.2" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="16097.2"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@@ -15,17 +15,17 @@
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<view id="9Nv-Zl-Z9p">
<rect key="frame" x="0.0" y="0.0" width="571" height="320"/>
<rect key="frame" x="0.0" y="0.0" width="600" height="302"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<stackView orientation="horizontal" alignment="centerY" spacing="2" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" translatesAutoresizingMaskIntoConstraints="NO" id="ITj-5P-sn9">
<rect key="frame" x="20" y="0.0" width="551" height="320"/>
<middleViews>
<stackView orientation="vertical" alignment="centerX" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="jd3-xw-cZP">
<rect key="frame" x="165" y="0.0" width="222" height="320"/>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="JV1-lh-OtN" userLabel="Side Buttons Holder">
<rect key="frame" x="0.0" y="0.0" width="401" height="302"/>
<subviews>
<stackView orientation="vertical" alignment="centerX" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" translatesAutoresizingMaskIntoConstraints="NO" id="jd3-xw-cZP">
<rect key="frame" x="90" y="40" width="222" height="222"/>
<middleViews>
<imageView misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="VWi-da-LGh">
<rect key="frame" x="47" y="115" width="128" height="128"/>
<imageView translatesAutoresizingMaskIntoConstraints="NO" id="VWi-da-LGh">
<rect key="frame" x="47" y="94" width="128" height="128"/>
<constraints>
<constraint firstAttribute="height" constant="128" id="T0d-gp-edr"/>
<constraint firstAttribute="width" constant="128" id="Xdf-jE-D9H"/>
@@ -33,15 +33,13 @@
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="MacPassAppIcon" id="9f2-Co-St2"/>
</imageView>
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="EEg-rH-sPx">
<rect key="frame" x="-2" y="78" width="226" height="29"/>
<rect key="frame" x="-2" y="58" width="226" height="28"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Welcome to MacPass" id="zdv-z8-khG">
<font key="font" metaFont="system" size="24"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</middleViews>
<endViews>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="MmF-PL-dgZ">
<rect key="frame" x="39" y="22" width="144" height="32"/>
<buttonCell key="cell" type="push" title="Open Database…" bezelStyle="rounded" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Jj3-zy-gaz">
@@ -54,7 +52,7 @@
</button>
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="IRO-Hz-Zjp">
<rect key="frame" x="26" y="-7" width="170" height="32"/>
<buttonCell key="cell" type="push" title="Create new Database" bezelStyle="rounded" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Vxx-Ql-eI5">
<buttonCell key="cell" type="push" title="Create Database" bezelStyle="rounded" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Vxx-Ql-eI5">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
@@ -62,10 +60,7 @@
<action selector="createNewDatabase:" target="-1" id="hbV-Rz-x5g"/>
</connections>
</button>
</endViews>
<constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="300" id="f86-vL-FmV"/>
</constraints>
</middleViews>
<visibilityPriorities>
<integer value="1000"/>
<integer value="1000"/>
@@ -79,115 +74,105 @@
<real value="3.4028234663852886e+38"/>
</customSpacing>
</stackView>
</middleViews>
<endViews>
<scrollView misplaced="YES" autohidesScrollers="YES" horizontalLineScroll="40" horizontalPageScroll="10" verticalLineScroll="40" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="eUA-6g-T1O">
<rect key="frame" x="389" y="0.0" width="162" height="320"/>
<clipView key="contentView" id="0Kf-Fq-by2">
<rect key="frame" x="1" y="1" width="160" height="318"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnReordering="NO" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" rowHeight="38" rowSizeStyle="automatic" viewBased="YES" id="51b-Ql-3gM">
<rect key="frame" x="0.0" y="0.0" width="160" height="318"/>
<autoresizingMask key="autoresizingMask"/>
<size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
<tableColumns>
<tableColumn width="157" minWidth="40" maxWidth="1000" id="oLj-wZ-syY">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
</tableHeaderCell>
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" title="Text Cell" id="Fbl-HT-XIu">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
<prototypeCellViews>
<tableCellView id="6UF-Gr-4nf">
<rect key="frame" x="1" y="1" width="157" height="38"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Kko-1G-JNn">
<rect key="frame" x="2" y="3" width="32" height="32"/>
<constraints>
<constraint firstAttribute="width" secondItem="Kko-1G-JNn" secondAttribute="height" multiplier="1:1" id="DCx-UU-29t"/>
<constraint firstAttribute="height" constant="32" id="tUG-uX-FuQ"/>
</constraints>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="NSActionTemplate" id="9TF-9t-7gd"/>
</imageView>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" allowsExpansionToolTips="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Kso-jb-pRH">
<rect key="frame" x="39" y="11" width="118" height="17"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="vzM-ly-CYn">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<constraints>
<constraint firstItem="Kso-jb-pRH" firstAttribute="centerY" secondItem="6UF-Gr-4nf" secondAttribute="centerY" id="EFe-Eu-cwW"/>
<constraint firstItem="Kso-jb-pRH" firstAttribute="leading" secondItem="Kko-1G-JNn" secondAttribute="trailing" constant="7" id="Jlp-gO-6rv"/>
<constraint firstItem="Kko-1G-JNn" firstAttribute="leading" secondItem="6UF-Gr-4nf" secondAttribute="leading" constant="2" id="RV0-o5-iyA"/>
<constraint firstItem="Kko-1G-JNn" firstAttribute="centerY" secondItem="6UF-Gr-4nf" secondAttribute="centerY" id="oFg-c1-o9M"/>
<constraint firstAttribute="trailing" secondItem="Kso-jb-pRH" secondAttribute="trailing" constant="2" id="ptI-vC-fK9"/>
</constraints>
<connections>
<outlet property="imageView" destination="Kko-1G-JNn" id="AvW-EL-9Rw"/>
<outlet property="textField" destination="Kso-jb-pRH" id="yWg-4p-sFp"/>
</connections>
</tableCellView>
</prototypeCellViews>
</tableColumn>
</tableColumns>
<connections>
<action trigger="doubleAction" selector="openRecentURL:" target="-2" id="kTu-60-aYp"/>
<outlet property="dataSource" destination="-2" id="pLD-5Q-GVH"/>
<outlet property="delegate" destination="-2" id="hO0-G9-RVy"/>
</connections>
</tableView>
</subviews>
</clipView>
<constraints>
<constraint firstAttribute="width" constant="200" id="R0Z-La-Y3C"/>
</constraints>
<scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="bRy-ef-e76">
<rect key="frame" x="1" y="303" width="135" height="16"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
<scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="2e9-uR-dY7">
<rect key="frame" x="224" y="17" width="15" height="102"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
</scrollView>
</endViews>
</subviews>
<constraints>
<constraint firstAttribute="bottom" secondItem="jd3-xw-cZP" secondAttribute="bottom" constant="20" id="581-be-EbR"/>
<constraint firstItem="jd3-xw-cZP" firstAttribute="top" secondItem="ITj-5P-sn9" secondAttribute="top" constant="20" id="9he-mz-Ciw"/>
<constraint firstAttribute="bottom" secondItem="eUA-6g-T1O" secondAttribute="bottom" constant="-1" id="Ejt-qZ-puH"/>
<constraint firstAttribute="trailing" secondItem="eUA-6g-T1O" secondAttribute="trailing" constant="-1" id="PEw-In-uMJ"/>
<constraint firstItem="eUA-6g-T1O" firstAttribute="top" secondItem="ITj-5P-sn9" secondAttribute="top" constant="-1" id="piI-8Q-zsE"/>
<constraint firstItem="jd3-xw-cZP" firstAttribute="centerX" secondItem="JV1-lh-OtN" secondAttribute="centerX" id="8C8-ZW-58v"/>
<constraint firstItem="jd3-xw-cZP" firstAttribute="centerY" secondItem="JV1-lh-OtN" secondAttribute="centerY" id="HeM-vT-DHO"/>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="300" id="LaQ-Zq-f9E"/>
</constraints>
<visibilityPriorities>
<integer value="1000"/>
<integer value="1000"/>
</visibilityPriorities>
<customSpacing>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
</customSpacing>
</stackView>
</customView>
<scrollView autohidesScrollers="YES" horizontalLineScroll="40" horizontalPageScroll="10" verticalLineScroll="40" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="eUA-6g-T1O">
<rect key="frame" x="401" y="-1" width="200" height="304"/>
<clipView key="contentView" id="0Kf-Fq-by2">
<rect key="frame" x="1" y="1" width="198" height="302"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" columnReordering="NO" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" rowHeight="38" rowSizeStyle="automatic" viewBased="YES" id="51b-Ql-3gM">
<rect key="frame" x="0.0" y="0.0" width="198" height="302"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
<tableColumns>
<tableColumn width="195" minWidth="40" maxWidth="1000" id="oLj-wZ-syY">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border">
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
</tableHeaderCell>
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" title="Text Cell" id="Fbl-HT-XIu">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
<prototypeCellViews>
<tableCellView id="6UF-Gr-4nf">
<rect key="frame" x="1" y="1" width="195" height="38"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Kko-1G-JNn">
<rect key="frame" x="2" y="3" width="32" height="32"/>
<constraints>
<constraint firstAttribute="width" secondItem="Kko-1G-JNn" secondAttribute="height" multiplier="1:1" id="DCx-UU-29t"/>
<constraint firstAttribute="height" constant="32" id="tUG-uX-FuQ"/>
</constraints>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="NSActionTemplate" id="9TF-9t-7gd"/>
</imageView>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" allowsExpansionToolTips="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Kso-jb-pRH">
<rect key="frame" x="39" y="11" width="156" height="16"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="vzM-ly-CYn">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<constraints>
<constraint firstItem="Kso-jb-pRH" firstAttribute="centerY" secondItem="6UF-Gr-4nf" secondAttribute="centerY" id="EFe-Eu-cwW"/>
<constraint firstItem="Kso-jb-pRH" firstAttribute="leading" secondItem="Kko-1G-JNn" secondAttribute="trailing" constant="7" id="Jlp-gO-6rv"/>
<constraint firstItem="Kko-1G-JNn" firstAttribute="leading" secondItem="6UF-Gr-4nf" secondAttribute="leading" constant="2" id="RV0-o5-iyA"/>
<constraint firstItem="Kko-1G-JNn" firstAttribute="centerY" secondItem="6UF-Gr-4nf" secondAttribute="centerY" id="oFg-c1-o9M"/>
<constraint firstAttribute="trailing" secondItem="Kso-jb-pRH" secondAttribute="trailing" constant="2" id="ptI-vC-fK9"/>
</constraints>
<connections>
<outlet property="imageView" destination="Kko-1G-JNn" id="AvW-EL-9Rw"/>
<outlet property="textField" destination="Kso-jb-pRH" id="yWg-4p-sFp"/>
</connections>
</tableCellView>
</prototypeCellViews>
</tableColumn>
</tableColumns>
<connections>
<action trigger="doubleAction" selector="openRecentURL:" target="-2" id="kTu-60-aYp"/>
<outlet property="dataSource" destination="-2" id="pLD-5Q-GVH"/>
<outlet property="delegate" destination="-2" id="hO0-G9-RVy"/>
</connections>
</tableView>
</subviews>
</clipView>
<constraints>
<constraint firstAttribute="width" constant="200" id="R0Z-La-Y3C"/>
</constraints>
<scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="bRy-ef-e76">
<rect key="frame" x="1" y="287" width="198" height="16"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
<scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="2e9-uR-dY7">
<rect key="frame" x="224" y="17" width="15" height="102"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
</scrollView>
</subviews>
<constraints>
<constraint firstAttribute="trailing" secondItem="ITj-5P-sn9" secondAttribute="trailing" id="7Bo-Jl-7Zu"/>
<constraint firstItem="ITj-5P-sn9" firstAttribute="top" secondItem="9Nv-Zl-Z9p" secondAttribute="top" id="lrE-f8-tD5"/>
<constraint firstItem="ITj-5P-sn9" firstAttribute="leading" secondItem="9Nv-Zl-Z9p" secondAttribute="leading" constant="20" id="oWL-PJ-VCT"/>
<constraint firstAttribute="bottom" secondItem="ITj-5P-sn9" secondAttribute="bottom" id="syW-TO-uwv"/>
<constraint firstAttribute="bottom" secondItem="eUA-6g-T1O" secondAttribute="bottom" constant="-1" id="6ri-AE-xpC"/>
<constraint firstItem="eUA-6g-T1O" firstAttribute="top" secondItem="9Nv-Zl-Z9p" secondAttribute="top" constant="-1" id="D5N-Fq-0LP"/>
<constraint firstItem="JV1-lh-OtN" firstAttribute="top" secondItem="9Nv-Zl-Z9p" secondAttribute="top" id="RPE-bR-zfc"/>
<constraint firstAttribute="trailing" secondItem="eUA-6g-T1O" secondAttribute="trailing" constant="-1" id="VMx-Ef-cEG"/>
<constraint firstItem="JV1-lh-OtN" firstAttribute="leading" secondItem="9Nv-Zl-Z9p" secondAttribute="leading" id="W2e-Nw-pfi"/>
<constraint firstItem="eUA-6g-T1O" firstAttribute="leading" secondItem="JV1-lh-OtN" secondAttribute="trailing" id="Z02-i4-6Jm"/>
<constraint firstAttribute="bottom" secondItem="JV1-lh-OtN" secondAttribute="bottom" id="ow6-hF-qkt"/>
</constraints>
<point key="canvasLocation" x="-680" y="-522"/>
<point key="canvasLocation" x="-714" y="-522"/>
</view>
</objects>
<resources>

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="15702" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15702"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17701"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@@ -11,6 +11,7 @@
<outlet property="browserPopup" destination="ehI-gq-lsb" id="YMy-L1-pQw"/>
<outlet property="doubleClickTitlePopup" destination="40" id="aKJ-q9-xjb"/>
<outlet property="doubleClickURLPopup" destination="13" id="fGP-5I-0XK"/>
<outlet property="generatePasswordOnEntriesCheckButton" destination="yxq-YK-61i" id="0SK-CT-Wdn"/>
<outlet property="hideAfterCopyToClipboardCheckButton" destination="vT4-wF-ned" id="d7e-vc-cAQ"/>
<outlet property="updatePasswordOnTemplateEntriesCheckButton" destination="LPY-sM-hjS" id="wav-op-uck"/>
<outlet property="view" destination="1" id="52"/>
@@ -19,16 +20,16 @@
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="1">
<rect key="frame" x="0.0" y="0.0" width="400" height="314"/>
<rect key="frame" x="0.0" y="0.0" width="449" height="338"/>
<subviews>
<box autoresizesSubviews="NO" verticalHuggingPriority="500" borderType="line" title="Entry Table" translatesAutoresizingMaskIntoConstraints="NO" id="2">
<rect key="frame" x="17" y="166" width="366" height="99"/>
<box autoresizesSubviews="NO" horizontalHuggingPriority="249" verticalHuggingPriority="500" borderType="line" title="Entry Table" translatesAutoresizingMaskIntoConstraints="NO" id="2">
<rect key="frame" x="17" y="194" width="415" height="96"/>
<view key="contentView" id="cfa-nq-Kzt">
<rect key="frame" x="3" y="3" width="360" height="81"/>
<rect key="frame" x="3" y="3" width="409" height="78"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="9">
<rect key="frame" x="18" y="53" width="134" height="16"/>
<rect key="frame" x="18" y="51" width="134" height="16"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="Double-click on URL:" id="10">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@@ -36,10 +37,10 @@
</textFieldCell>
</textField>
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="13">
<rect key="frame" x="156" y="47" width="109" height="25"/>
<rect key="frame" x="155" y="44" width="110" height="25"/>
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="14">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<font key="font" metaFont="menu"/>
<menu key="menu" title="OtherViews" id="15">
<items>
<menuItem title="Copies URL" id="16"/>
@@ -49,7 +50,7 @@
</popUpButtonCell>
</popUpButton>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="36">
<rect key="frame" x="18" y="22" width="134" height="16"/>
<rect key="frame" x="18" y="21" width="134" height="16"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" enabled="NO" sendsActionOnEndEditing="YES" title="Double-click on Title:" id="37">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@@ -57,10 +58,10 @@
</textFieldCell>
</textField>
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="40">
<rect key="frame" x="156" y="17" width="139" height="24"/>
<rect key="frame" x="155" y="16" width="140" height="23"/>
<popUpButtonCell key="cell" type="push" title="Opens Inspector" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="44" id="41">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<font key="font" metaFont="menu"/>
<menu key="menu" title="OtherViews" id="42">
<items>
<menuItem title="Opens Inspector" state="on" id="44"/>
@@ -90,10 +91,10 @@
</constraints>
</box>
<popUpButton verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ehI-gq-lsb">
<rect key="frame" x="113" y="270" width="135" height="25"/>
<rect key="frame" x="112" y="294" width="136" height="25"/>
<popUpButtonCell key="cell" type="push" title="Default Browser" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="7YX-EA-9KA" id="7Ip-sU-sAK">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<font key="font" metaFont="menu"/>
<menu key="menu" title="OtherViews" id="XgO-Tj-QjO">
<items>
<menuItem title="Default Browser" state="on" id="7YX-EA-9KA"/>
@@ -104,22 +105,29 @@
</popUpButtonCell>
</popUpButton>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="lOo-NI-b07">
<rect key="frame" x="18" y="273" width="91" height="19"/>
<rect key="frame" x="18" y="301" width="91" height="16"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" enabled="NO" sendsActionOnEndEditing="YES" title="Open URLs in:" id="soD-wI-YOH">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<box borderType="line" title="Templates" translatesAutoresizingMaskIntoConstraints="NO" id="Xvt-tP-TbR">
<rect key="frame" x="17" y="92" width="366" height="72"/>
<box horizontalHuggingPriority="249" borderType="line" title="New Entries" translatesAutoresizingMaskIntoConstraints="NO" id="Xvt-tP-TbR">
<rect key="frame" x="17" y="94" width="415" height="96"/>
<view key="contentView" id="g0i-00-sng">
<rect key="frame" x="3" y="3" width="360" height="54"/>
<rect key="frame" x="3" y="3" width="409" height="78"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="LPY-sM-hjS">
<rect key="frame" x="18" y="18" width="222" height="18"/>
<buttonCell key="cell" type="check" title="Update password for new entries" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="RaM-t2-DVR">
<rect key="frame" x="18" y="41" width="354" height="18"/>
<buttonCell key="cell" type="check" title="Generate password for entries created from templates" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="RaM-t2-DVR">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="yxq-YK-61i">
<rect key="frame" x="18" y="19" width="238" height="18"/>
<buttonCell key="cell" type="check" title="Generate password for new entries" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="iCq-mG-p81">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
@@ -127,20 +135,23 @@
</subviews>
<constraints>
<constraint firstItem="LPY-sM-hjS" firstAttribute="top" secondItem="g0i-00-sng" secondAttribute="top" constant="20" symbolic="YES" id="Ip3-vX-0L9"/>
<constraint firstItem="yxq-YK-61i" firstAttribute="leading" secondItem="LPY-sM-hjS" secondAttribute="leading" id="LfJ-z5-Q3P"/>
<constraint firstItem="LPY-sM-hjS" firstAttribute="leading" secondItem="g0i-00-sng" secondAttribute="leading" constant="20" symbolic="YES" id="RE9-Jf-nFR"/>
<constraint firstAttribute="bottom" secondItem="LPY-sM-hjS" secondAttribute="bottom" constant="20" symbolic="YES" id="nGd-XA-Jj9"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="yxq-YK-61i" secondAttribute="trailing" constant="20" symbolic="YES" id="WHR-l8-6ce"/>
<constraint firstAttribute="bottom" secondItem="yxq-YK-61i" secondAttribute="bottom" constant="20" symbolic="YES" id="rNE-sZ-z2e"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="LPY-sM-hjS" secondAttribute="trailing" constant="20" symbolic="YES" id="wyU-eZ-BSC"/>
<constraint firstItem="yxq-YK-61i" firstAttribute="top" secondItem="LPY-sM-hjS" secondAttribute="bottom" constant="6" symbolic="YES" id="yNh-4f-kMr"/>
</constraints>
</view>
</box>
<box title="Clipboard" translatesAutoresizingMaskIntoConstraints="NO" id="Kff-Xp-hAT">
<rect key="frame" x="17" y="16" width="366" height="72"/>
<box horizontalHuggingPriority="249" title="Clipboard" translatesAutoresizingMaskIntoConstraints="NO" id="Kff-Xp-hAT">
<rect key="frame" x="17" y="16" width="415" height="74"/>
<view key="contentView" id="Ntf-zj-VZL">
<rect key="frame" x="3" y="3" width="360" height="54"/>
<rect key="frame" x="3" y="3" width="409" height="56"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="vT4-wF-ned">
<rect key="frame" x="18" y="18" width="280" height="18"/>
<rect key="frame" x="18" y="19" width="284" height="18"/>
<buttonCell key="cell" type="check" title="Hide application after copying to clipboard" bezelStyle="regularSquare" imagePosition="left" inset="2" id="1Vr-nY-Ogv">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
@@ -159,12 +170,11 @@
<constraints>
<constraint firstItem="2" firstAttribute="leading" secondItem="1" secondAttribute="leading" constant="20" symbolic="YES" id="5"/>
<constraint firstAttribute="trailing" secondItem="2" secondAttribute="trailing" constant="20" symbolic="YES" id="8"/>
<constraint firstAttribute="width" constant="400" id="53"/>
<constraint firstItem="Kff-Xp-hAT" firstAttribute="top" secondItem="Xvt-tP-TbR" secondAttribute="bottom" constant="8" symbolic="YES" id="3RL-tm-4wu"/>
<constraint firstAttribute="bottom" secondItem="Kff-Xp-hAT" secondAttribute="bottom" constant="20" symbolic="YES" id="8k6-1d-wPj"/>
<constraint firstItem="Xvt-tP-TbR" firstAttribute="leading" secondItem="1" secondAttribute="leading" constant="20" symbolic="YES" id="BH4-4y-uma"/>
<constraint firstItem="2" firstAttribute="top" secondItem="ehI-gq-lsb" secondAttribute="bottom" constant="8" symbolic="YES" id="CnN-aU-Qa1"/>
<constraint firstItem="Xvt-tP-TbR" firstAttribute="top" secondItem="cfa-nq-Kzt" secondAttribute="bottom" constant="5" id="FVK-Uf-kLv"/>
<constraint firstItem="Xvt-tP-TbR" firstAttribute="top" secondItem="2" secondAttribute="bottom" constant="8" symbolic="YES" id="FVK-Uf-kLv"/>
<constraint firstItem="ehI-gq-lsb" firstAttribute="leading" secondItem="lOo-NI-b07" secondAttribute="trailing" constant="8" symbolic="YES" id="KxB-TG-rH5"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="ehI-gq-lsb" secondAttribute="trailing" constant="20" symbolic="YES" id="Ldw-aO-wuX"/>
<constraint firstItem="ehI-gq-lsb" firstAttribute="top" secondItem="1" secondAttribute="top" constant="20" symbolic="YES" id="MAe-l7-8k2"/>
@@ -173,9 +183,8 @@
<constraint firstAttribute="trailing" secondItem="Xvt-tP-TbR" secondAttribute="trailing" constant="20" id="anU-nC-YAw"/>
<constraint firstItem="lOo-NI-b07" firstAttribute="firstBaseline" secondItem="ehI-gq-lsb" secondAttribute="firstBaseline" id="gFK-Ce-Q3b"/>
<constraint firstItem="lOo-NI-b07" firstAttribute="leading" secondItem="1" secondAttribute="leading" constant="20" symbolic="YES" id="kaP-lB-tDY"/>
<constraint firstItem="2" firstAttribute="top" secondItem="lOo-NI-b07" secondAttribute="bottom" constant="8" symbolic="YES" id="xlS-Dj-cOt"/>
</constraints>
<point key="canvasLocation" x="-2" y="125"/>
<point key="canvasLocation" x="-752" y="-257"/>
</customView>
</objects>
</document>

View File

@@ -29,12 +29,10 @@
@implementation DDHotKey (MPKeydata)
+ (NSData *)hotKeyDataWithKeyCode:(unsigned short)keyCode modifierFlags:(NSUInteger)flags {
NSMutableData *data = [[NSMutableData alloc] init];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initRequiringSecureCoding:YES];
[archiver encodeInt:keyCode forKey:NSStringFromSelector(@selector(keyCode))];
[archiver encodeInteger:flags forKey:NSStringFromSelector(@selector(modifierFlags))];
[archiver finishEncoding];
return [data copy];
return [archiver.encodedData copy];
}
+ (NSData *)defaultHotKeyData {
@@ -73,7 +71,13 @@
if(keyCode == NULL || modifierFlags == NULL || data == nil) {
return NO;
}
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
NSError *error;
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:data error:&error];
if(error) {
NSLog(@"Error while trying to decode DDHotKey %@", error.localizedDescription);
return NO;
}
*keyCode = [unarchiver decodeIntForKey:NSStringFromSelector(@selector(keyCode))];
*modifierFlags = [unarchiver decodeIntegerForKey:NSStringFromSelector(@selector(modifierFlags))];
return YES;
@@ -86,19 +90,19 @@
NSEventModifierFlags flags = 0;
switch(self.keyCode) {
case kVK_Command:
flags = NSCommandKeyMask;
flags = NSEventModifierFlagCommand;
break;
case kVK_Shift:
case kVK_RightShift:
flags = NSShiftKeyMask;
flags = NSEventModifierFlagShift;
break;
case kVK_Option:
case kVK_RightOption:
flags = NSAlternateKeyMask;
flags = NSEventModifierFlagOption;
break;
case kVK_Control:
case kVK_RightControl:
flags = NSControlKeyMask;
flags = NSEventModifierFlagControl;
break;
}
BOOL missingModifier = self.modifierFlags == 0;

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17701"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="MPDocumentSplitViewController">
<connections>
<outlet property="view" destination="Hz6-mo-xeY" id="0bl-1N-x8E"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="Hz6-mo-xeY">
<rect key="frame" x="0.0" y="0.0" width="480" height="272"/>
<point key="canvasLocation" x="141" y="154"/>
</customView>
</objects>
</document>

View File

@@ -1,32 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="13771" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="15705" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13771"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="15705"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="MPDocumentWindowController">
<connections>
<outlet property="splitView" destination="697" id="700"/>
<outlet property="window" destination="1" id="501"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" frameAutosaveName="DatabaseWindow" animationBehavior="default" tabbingMode="preferred" id="1">
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" frameAutosaveName="DatabaseWindow" animationBehavior="default" tabbingMode="preferred" id="1">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<windowCollectionBehavior key="collectionBehavior" fullScreenPrimary="YES"/>
<rect key="contentRect" x="196" y="240" width="700" height="500"/>
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1417"/>
<view key="contentView" id="2">
<rect key="frame" x="0.0" y="0.0" width="700" height="500"/>
<autoresizingMask key="autoresizingMask"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
</view>
<point key="canvasLocation" x="54" y="51"/>
<point key="canvasLocation" x="256" y="42"/>
</window>
<splitView autosaveName="" dividerStyle="thin" vertical="YES" translatesAutoresizingMaskIntoConstraints="NO" id="697">
<rect key="frame" x="0.0" y="0.0" width="560" height="194"/>
</splitView>
</objects>
</document>

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17701"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@@ -15,25 +15,24 @@
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="336">
<rect key="frame" x="0.0" y="0.0" width="694" height="594"/>
<customView misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="336">
<rect key="frame" x="0.0" y="0.0" width="695" height="523"/>
<subviews>
<scrollView focusRingType="none" borderType="none" autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="54">
<rect key="frame" x="0.0" y="0.0" width="694" height="595"/>
<rect key="frame" x="0.0" y="0.0" width="695" height="524"/>
<clipView key="contentView" id="4tt-2K-SPF">
<rect key="frame" x="0.0" y="0.0" width="694" height="595"/>
<rect key="frame" x="0.0" y="0.0" width="695" height="524"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" alternatingRowBackgroundColors="YES" rowSizeStyle="automatic" headerView="676" viewBased="YES" id="55" customClass="MPTableView">
<rect key="frame" x="0.0" y="0.0" width="694" height="572"/>
<autoresizingMask key="autoresizingMask"/>
<rect key="frame" x="0.0" y="0.0" width="695" height="501"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
<tableColumns>
<tableColumn identifier="Group Column" width="104.609375" minWidth="40" maxWidth="3.4028234663852886e+38" id="117">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
</tableHeaderCell>
@@ -49,7 +48,7 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="270">
<rect key="frame" x="1" y="0.0" width="103" height="17"/>
<rect key="frame" x="1" y="1" width="103" height="16"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="271">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@@ -70,7 +69,6 @@
</tableColumn>
<tableColumn identifier="Title Column" width="144.1171875" minWidth="40" maxWidth="3.4028234663852886e+38" id="119">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
</tableHeaderCell>
@@ -119,7 +117,6 @@
</tableColumn>
<tableColumn identifier="Password Column" width="118.73046875" minWidth="10" maxWidth="3.4028234663852886e+38" id="232">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
</tableHeaderCell>
@@ -135,7 +132,7 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="429" customClass="NSSecureTextField">
<rect key="frame" x="1" y="0.0" width="116" height="17"/>
<rect key="frame" x="1" y="1" width="116" height="16"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="430">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@@ -156,7 +153,6 @@
</tableColumn>
<tableColumn identifier="URL Column" width="113.18359375" minWidth="10" maxWidth="3.4028234663852886e+38" id="419">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
</tableHeaderCell>
@@ -172,7 +168,7 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="422">
<rect key="frame" x="1" y="0.0" width="111" height="17"/>
<rect key="frame" x="1" y="1" width="111" height="16"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="423">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@@ -191,9 +187,8 @@
</tableCellView>
</prototypeCellViews>
</tableColumn>
<tableColumn width="199" minWidth="10" maxWidth="3.4028234663852886e+38" id="614">
<tableColumn width="200" minWidth="10" maxWidth="3.4028234663852886e+38" id="614">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
</tableHeaderCell>
@@ -205,11 +200,11 @@
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
<prototypeCellViews>
<tableCellView id="616">
<rect key="frame" x="493" y="1" width="199" height="17"/>
<rect key="frame" x="493" y="1" width="200" height="17"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="617">
<rect key="frame" x="1" y="0.0" width="197" height="17"/>
<rect key="frame" x="1" y="1" width="198" height="16"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="618">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@@ -241,7 +236,7 @@
<autoresizingMask key="autoresizingMask"/>
</scroller>
<tableHeaderView key="headerView" id="676">
<rect key="frame" x="0.0" y="0.0" width="694" height="23"/>
<rect key="frame" x="0.0" y="0.0" width="695" height="23"/>
<autoresizingMask key="autoresizingMask"/>
</tableHeaderView>
</scrollView>

View File

@@ -0,0 +1,17 @@
//
// KPKBinary+MacPassAddtions.h
// MacPass
//
// Created by Michael Starke on 09.11.20.
// Copyright © 2020 HicknHack Software GmbH. All rights reserved.
//
#import <KeePassKit/KeePassKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface KPKBinary (MacPassAddtions) <NSFilePromiseProviderDelegate>
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,23 @@
//
// KPKBinary+MacPassAddtions.m
// MacPass
//
// Created by Michael Starke on 09.11.20.
// Copyright © 2020 HicknHack Software GmbH. All rights reserved.
//
#import "KPKBinary+MacPassAddtions.h"
@implementation KPKBinary (MacPassAddtions)
- (NSString *)filePromiseProvider:(NSFilePromiseProvider *)filePromiseProvider fileNameForType:(NSString *)fileType {
return self.name;
}
- (void)filePromiseProvider:(NSFilePromiseProvider *)filePromiseProvider writePromiseToURL:(NSURL *)url completionHandler:(void (^)(NSError * _Nullable))completionHandler {
NSError *error;
[self saveToLocation:url error:&error];
completionHandler(error);
}
@end

View File

@@ -23,17 +23,16 @@
#import "MPAddCustomFieldContextMenuDelegate.h"
#import "KeePassKit/KeePassKit.h"
NSString *const MPHMACOTPSeedAttributeKey = @"HMACOTP-Seed";
NSString *const MPHMACOTPConfigAttributeKey = @"HMACOTP-Config";
#import "MPEntryInspectorViewController.h"
/*
HmacOtp-Secret (the UTF-8 representation of the value is the secret),
HmacOtp-Secret-Hex (secret as hex string),
HmacOtp-Secret-Base32 (secret as Base32 string)
HmacOtp-Secret-Base64 (secret as Base64 string)
HmacOtp-Secret (the UTF-8 representation of the value is the secret),
HmacOtp-Secret-Hex (secret as hex string),
HmacOtp-Secret-Base32 (secret as Base32 string)
HmacOtp-Secret-Base64 (secret as Base64 string)
HmacOtp-Counter field.
*/
HmacOtp-Counter field.
*/
@interface MPAddCustomFieldContextMenuDelegate ()
@property (readonly, nonatomic) KPKEntry *entry;
@@ -51,30 +50,29 @@ HmacOtp-Counter field.
- (void)menuNeedsUpdate:(NSMenu *)menu {
[menu removeAllItems];
//[self _setupHOTPMenuItemsToMenu:menu];
[self _setupHOTPMenuItemsToMenu:menu];
[self _setupTOTPMenuItemsToMenu:menu];
}
/* HMAC OTP */
- (void)_setupHOTPMenuItemsToMenu:(NSMenu *)menu {
BOOL hasConfigAttribute = nil != [self.entry customAttributeWithKey:MPHMACOTPConfigAttributeKey];
if(!hasConfigAttribute) {
NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"ADD_CUSTOM_ATTRIBUTE_HMACOTP_CONFIG", @"Menu item title for adding an hmacotp config attribute") action:@selector(_addHMACConfig:) keyEquivalent:@""];
item.target = self;
[menu addItem:item];
}
BOOL hasSeedAttribute = nil != [self.entry customAttributeWithKey:MPHMACOTPSeedAttributeKey];
if(!hasSeedAttribute) {
NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"ADD_CUSTOM_ATTRIBUTE_HMACOTP_SEED", @"Menu item title for adding an hmacotp seed attribute") action:@selector(_addHMACSeed:) keyEquivalent:@""];
item.target = self;
[menu addItem:item];
}
}
- (IBAction)_setupHMACConfig:(id)sender {
}
- (IBAction)_delteHMACConfig:(id)sender {
}
- (IBAction)_addHMACConfig:(id)sender {
[self.entry addCustomAttribute:[[KPKAttribute alloc] initWithKey:MPHMACOTPConfigAttributeKey value:@"<config>"]];
/* Time OPT*/
- (void)_setupTOTPMenuItemsToMenu:(NSMenu *)menu {
NSMenuItem *setupItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"SETUP_TOTP_SETTINGS", @"Menu item title editing TOTP settings") action:@selector(showOTPSetup:) keyEquivalent:@""];
setupItem.target = self.viewController;
[menu addItem:setupItem];
}
- (IBAction)_addHMACSeed:(id)sender {
[self.entry addCustomAttribute:[[KPKAttribute alloc] initWithKey:MPHMACOTPSeedAttributeKey value:@"<seed>"]];
}
- (IBAction)_setupTOTPSettings:(id)sender {}
- (IBAction)_deleteTOTPSettings:(id)sender {}
@end

View File

@@ -100,13 +100,8 @@ typedef NS_OPTIONS(NSInteger, MPAppStartupState) {
object:nil];
/* We know that we do not use the variable after instantiation */
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-variable"
MPDocumentController *documentController = [[MPDocumentController alloc] init];
#pragma clang diagnostic pop
NSAssert(documentController, @"Custom document controller cannot be nil");
}
return self;
}
@@ -224,11 +219,7 @@ typedef NS_OPTIONS(NSInteger, MPAppStartupState) {
#endif
self.startupState |= MPAppStartupStateFinishedLaunch;
// Here we just opt-in for allowing our bar to be customized throughout the app.
if([NSApplication.sharedApplication respondsToSelector:@selector(isAutomaticCustomizeTouchBarMenuItemEnabled)]) {
if(@available(macOS 10.12.2, *)) {
NSApplication.sharedApplication.automaticCustomizeTouchBarMenuItemEnabled = YES;
}
}
NSApplication.sharedApplication.automaticCustomizeTouchBarMenuItemEnabled = YES;
}
#pragma mark -
@@ -236,12 +227,12 @@ typedef NS_OPTIONS(NSInteger, MPAppStartupState) {
- (void)menuNeedsUpdate:(NSMenu *)menu {
if(menu == self.saveMenuItem.menu) {
MPDocument *document = NSDocumentController.sharedDocumentController.currentDocument;
BOOL displayDots = (document.fileURL == nil || !document.compositeKey.hasPasswordOrKeyFile);
BOOL displayDots = (document.fileURL == nil || !document.compositeKey.hasKeys);
NSString *saveTitle = displayDots ? NSLocalizedString(@"SAVE_WITH_DOTS", "Save file menu item title when save will prompt for a location to save or ask for a password/key") : NSLocalizedString(@"SAVE", "Save file menu item title when save will just save the file");
self.saveMenuItem.title = saveTitle;
}
else if(menu == self.fixAutotypeMenuItem.menu) {
self.fixAutotypeMenuItem.hidden = !(NSEvent.modifierFlags & NSAlternateKeyMask);
self.fixAutotypeMenuItem.hidden = !(NSEvent.modifierFlags & NSEventModifierFlagOption);
}
else if(menu == self.importMenu) {
NSMenuItem *exportXML = menu.itemArray.firstObject;

View File

@@ -21,6 +21,7 @@
//
#import "MPAttachmentTableDataSource.h"
#import "KPKBinary+MacPassAddtions.h"
#import "MPDocument.h"
@implementation MPAttachmentTableDataSource
@@ -63,59 +64,16 @@
return YES;
}
- (BOOL)tableView:(NSTableView *)tableView writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard *)pboard {
[pboard declareTypes:@[NSFilesPromisePboardType] owner:nil];
MPDocument *document = tableView.window.windowController.document;
KPKEntry *entry = document.selectedEntries.count == 1 ? document.selectedEntries.lastObject : nil;
NSMutableArray *fileNames = [[NSMutableArray alloc] init];
for(KPKBinary *binary in [entry.binaries objectsAtIndexes:rowIndexes]) {
if(binary.name) {
[fileNames addObject:binary.name];
}
}
[pboard setPropertyList:fileNames forType:NSFilesPromisePboardType];
return YES;
}
- (NSArray<NSString *> *)tableView:(NSTableView *)tableView namesOfPromisedFilesDroppedAtDestination:(NSURL *)dropDestination forDraggedRowsWithIndexes:(NSIndexSet *)indexSet {
MPDocument *document = tableView.window.windowController.document;
KPKEntry *entry = document.selectedEntries.count == 1 ? document.selectedEntries.lastObject : nil;
NSMutableArray<NSString *> *fileNames = [[NSMutableArray alloc] init];
NSArray<KPKBinary *> *draggedBinaries = [entry.binaries objectsAtIndexes:indexSet];
for(KPKBinary *binary in draggedBinaries) {
if(binary.name) {
[fileNames addObject:binary.name];
dispatch_queue_t queue = dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0);
dispatch_async(queue, ^{
NSError *error;
NSURL *saveLocation = [dropDestination URLByAppendingPathComponent:binary.name];
BOOL success = [binary saveToLocation:saveLocation error:&error];
if(!success && error) {
dispatch_async(dispatch_get_main_queue(), ^{
[NSApp presentError:error];
});
}
});
}
}
return [fileNames copy];
}
/*
- (id<NSPasteboardWriting>)tableView:(NSTableView *)tableView pasteboardWriterForRow:(NSInteger)row {
- (id<NSPasteboardWriting>)tableView:(NSTableView *)tableView pasteboardWriterForRow:(NSInteger)row {
MPDocument *document = tableView.window.windowController.document;
KPKEntry *entry = document.selectedEntries.count == 1 ? document.selectedEntries.lastObject : nil;
if(!entry) {
return nil;
}
if (@available(macOS 10.12, *)) {
KPKBinary *binary = entry.binaries[row];
NSFilePromiseProvider *provider = [[NSFilePromiseProvider alloc] initWithFileType:(NSString *)kUTTypeXML delegate:binary];
return provider;
}
return nil;
KPKBinary *binary = entry.binaries[row];
NSFilePromiseProvider *provider = [[NSFilePromiseProvider alloc] initWithFileType:(NSString *)kUTTypeData delegate:binary];
return provider;
}
*/
@end

View File

@@ -33,7 +33,7 @@
@property (strong) IBOutlet NSButton *selectAutotypeContextButton;
@property (strong) IBOutlet NSTableView *contextTableView;
@property (strong) IBOutlet NSTextField *messageTextField;
@property (strong) IBOutlet NSImageView *targetApplicationImageView;
@end
@implementation MPAutotypeCandidateSelectionViewController
@@ -44,9 +44,27 @@
- (void)viewDidLoad {
[super viewDidLoad];
NSString *template = NSLocalizedString(@"AUTOTYPE_CANDIDATE_SELECTION_WINDOW_MESSAGE_%@", "Message text in the autotype selection window. Placeholder is %1 - windowTitle");
self.messageTextField.stringValue = [NSString stringWithFormat:template, self.environment.windowTitle];
self.selectAutotypeContextButton.enabled = NO;
NSRunningApplication *targetApplication = [NSRunningApplication runningApplicationWithProcessIdentifier:self.environment.pid];
if(nil != targetApplication) {
self.targetApplicationImageView.image = [self _composeInfoImage];
}
NSString *template = @"";
if(self.candidates.count > 1) {
template = NSLocalizedString(@"AUTOTYPE_CANDIDATE_SELECTION_WINDOW_MESSAGE_%@_%@", "Message text in the autotype selection window. Placeholder is %1 - applicationName, %2 windowTitle");
self.messageTextField.stringValue = [NSString stringWithFormat:template, targetApplication.localizedName, self.environment.windowTitle];
NSInteger rows = MIN(self.candidates.count, 5);
[self.contextTableView.enclosingScrollView.heightAnchor constraintGreaterThanOrEqualToConstant:39 * rows].active = YES;
}
else {
template = NSLocalizedString(@"AUTOTYPE_CANDIDATE_CONFIRMATION_WINDOW_MESSAGE_%@_%@", "Message text in the autotype confirmation window. Placeholder is %1 - applicationName, %2 windowTitle");
self.messageTextField.stringValue = [NSString stringWithFormat:template, targetApplication.localizedName, self.environment.windowTitle];
[self.contextTableView.enclosingScrollView.heightAnchor constraintEqualToConstant:39].active = YES;
}
NSNotification *notification = [NSNotification notificationWithName:NSTableViewSelectionDidChangeNotification object:self.contextTableView];
[self tableViewSelectionDidChange:notification];
}
@@ -91,5 +109,41 @@
[MPAutotypeDaemon.defaultDaemon cancelAutotypeContextSelectionForEnvironment:self.environment];
}
- (NSImage *)_composeInfoImage {
static const uint32_t iconSize = 64;
uint32_t imageWidth = 256;
uint32_t imageHeight = 256;
NSRunningApplication *targetApplication = [NSRunningApplication runningApplicationWithProcessIdentifier:self.environment.pid];
CGImageRef windowGrab = CGWindowListCreateImage(CGRectNull, kCGWindowListOptionIncludingWindow, self.environment.windowId, kCGWindowImageDefault | kCGWindowImageBestResolution);
NSImage *windowImage = [[NSImage alloc] initWithCGImage:windowGrab size:NSZeroSize];
CFRelease(windowGrab);
if(windowImage.size.width > windowImage.size.height) {
imageHeight = imageWidth * (windowImage.size.height / windowImage.size.width);
}
else {
imageWidth = imageWidth * (windowImage.size.width / windowImage.size.height);
}
if(!targetApplication.icon) {
return windowImage;
}
NSImage *composite = [[NSImage alloc] initWithSize:NSMakeSize(MAX(imageWidth, iconSize), MAX(imageHeight, iconSize))];
[composite lockFocus];
/* draw the image at the top left */
[windowImage drawInRect:NSMakeRect(composite.size.width - imageWidth, composite.size.height - imageHeight, imageWidth, imageHeight)
fromRect:NSZeroRect
operation:NSCompositingOperationSourceOver
fraction:1];
/* draw the app icon at the bottom left */
[targetApplication.icon drawInRect:NSMakeRect(0, 0, iconSize, iconSize)
fromRect:NSZeroRect
operation:NSCompositingOperationSourceOver
fraction:1];
[composite unlockFocus];
return composite;
}
@end

View File

@@ -143,13 +143,13 @@ static MPAutotypeDaemon *_sharedInstance;
- (void)performAutotypeForEntry:(KPKEntry *)entry overrideSequence:(NSString *)sequence {
if(entry) {
MPAutotypeEnvironment *env = [MPAutotypeEnvironment environmentWithTargetApplication:self.previousApplication entry:entry];
MPAutotypeEnvironment *env = [MPAutotypeEnvironment environmentWithTargetApplication:self.previousApplication entry:entry overrideSequence:sequence];
[self _runAutotypeWithEnvironment:env];
}
}
- (void)_didPressHotKey {
MPAutotypeEnvironment *env = [MPAutotypeEnvironment environmentWithTargetApplication:NSWorkspace.sharedWorkspace.frontmostApplication entry:nil];
MPAutotypeEnvironment *env = [MPAutotypeEnvironment environmentWithTargetApplication:NSWorkspace.sharedWorkspace.frontmostApplication entry:nil overrideSequence:nil];
[self _runAutotypeWithEnvironment:env];
}
@@ -278,10 +278,6 @@ static MPAutotypeDaemon *_sharedInstance;
}
- (MPAutotypeContext *)_autotypeContextForDocuments:(NSArray<MPDocument *> *)documents withEnvironment:(MPAutotypeEnvironment *)environment {
/*
Query the document to generate a autotype command list for the window title
We do not care where this came form, just get the autotype commands
*/
NSMutableArray *autotypeCandidates = [[NSMutableArray alloc] init];
for(MPDocument *document in documents) {
NSArray *contexts = [document autotypContextsForWindowTitle:environment.windowTitle preferredEntry:environment.preferredEntry];
@@ -290,16 +286,30 @@ static MPAutotypeDaemon *_sharedInstance;
}
}
if(autotypeCandidates.count <= 1) {
return autotypeCandidates.lastObject;
if(autotypeCandidates.count == 0) {
return nil; // we do not have found anything
}
[self _presentCandiadates:autotypeCandidates forEnvironment:environment];
return nil; // Nothing to do, we get called back by the window
/* present selection and return if more than one hit */
if(autotypeCandidates.count > 1) {
[self _presentCandiadates:autotypeCandidates forEnvironment:environment];
return nil;
}
BOOL isGlobalAutotype = (environment.preferredEntry == nil);
BOOL alwaysShowCandidateSelection = [NSUserDefaults.standardUserDefaults boolForKey:kMPSettingsKeyGloablAutotypeAlwaysShowCandidateSelection];
/* present confirmation if set on global autotype */
if(isGlobalAutotype && alwaysShowCandidateSelection) {
[self _presentCandiadates:autotypeCandidates forEnvironment:environment];
return nil;
}
/* return single hit */
return autotypeCandidates.firstObject;
}
- (void)_runAutotypeWithEnvironment:(MPAutotypeEnvironment *)environment forContext:(MPAutotypeContext *)context {
if(nil == environment) {
return; // no Environment to work in
return; // no environment to work in
}
if(nil == context) {
return; // No context to work with
@@ -309,7 +319,7 @@ static MPAutotypeDaemon *_sharedInstance;
[welf _runAutotypeWithEnvironment:environment forContext:context];
}];
if(!appIsFrontmost) {
return; // We will get called back when the application is in front - hopfully
return; // We will get called back when the application is in front
}
useconds_t globalDelay = 0;
@@ -363,8 +373,8 @@ static MPAutotypeDaemon *_sharedInstance;
- (void)_presentCandiadates:(NSArray *)candidates forEnvironment:(MPAutotypeEnvironment *)environment {
if(!self.matchSelectionWindow) {
self.matchSelectionWindow = [[NSPanel alloc] initWithContentRect:NSMakeRect(0, 0, 100, 100)
styleMask:NSWindowStyleMaskNonactivatingPanel|NSWindowStyleMaskTitled
backing:NSBackingStoreRetained
styleMask:NSWindowStyleMaskResizable|NSWindowStyleMaskNonactivatingPanel|NSWindowStyleMaskTitled
backing:NSBackingStoreBuffered
defer:YES];
self.matchSelectionWindow.level = kCGAssistiveTechHighWindowLevel;
MPAutotypeCandidateSelectionViewController *vc = [[MPAutotypeCandidateSelectionViewController alloc] init];

View File

@@ -21,12 +21,14 @@ NS_ASSUME_NONNULL_BEGIN
*/
@property (readonly, weak, nullable) KPKEntry *preferredEntry;
@property (readonly) pid_t pid; // the PID of the target application to which the key strokes should be sent
@property (readonly, copy) NSString *windowTitle; /// The window title of the target application.
@property (readonly) CGWindowID windowId; // the windowID of the target window of the target application
@property (readonly, copy) NSString *windowTitle; /// The title of the target window of the target application.
@property (readonly) BOOL hidden; /// If set to YES, MacPass was hidden when autotype was initiated
@property (readonly) BOOL isSelfTargeting; /// If MacPass should autotype to itself, YES, otherwise NO
@property (readonly) NSString *overrideSequence; /// If set, this sequence is used for running the command regardless of the matched one
+ (instancetype)environmentWithTargetApplication:(NSRunningApplication *)targetApplication entry:(KPKEntry * _Nullable)entry;
- (instancetype)initWithTargetApplication:(NSRunningApplication *)targetApplication entry:(KPKEntry * _Nullable)entry NS_DESIGNATED_INITIALIZER;
+ (instancetype)environmentWithTargetApplication:(NSRunningApplication *)targetApplication entry:(KPKEntry * _Nullable)entry overrideSequence:(NSString * _Nullable)overrideSequence;
- (instancetype)initWithTargetApplication:(NSRunningApplication *)targetApplication entry:(KPKEntry * _Nullable)entry overrideSequence:(NSString * _Nullable)overrdieSequence NS_DESIGNATED_INITIALIZER;
- (instancetype)init NS_UNAVAILABLE;
@end

View File

@@ -13,23 +13,27 @@
@implementation MPAutotypeEnvironment
+ (instancetype)environmentWithTargetApplication:(NSRunningApplication *)targetApplication entry:(KPKEntry *)entry {
return [[MPAutotypeEnvironment alloc] initWithTargetApplication:targetApplication entry:entry];
+ (instancetype)environmentWithTargetApplication:(NSRunningApplication *)targetApplication entry:(KPKEntry *)entry overrideSequence:(NSString *)overrideSequence {
return [[MPAutotypeEnvironment alloc] initWithTargetApplication:targetApplication entry:entry overrideSequence:overrideSequence];
}
- (instancetype)initWithTargetApplication:(NSRunningApplication *)targetApplication entry:(KPKEntry *)entry {
- (instancetype)initWithTargetApplication:(NSRunningApplication *)targetApplication entry:(KPKEntry *)entry overrideSequence:(NSString *)overrdieSequence {
self = [super init];
if(self) {
_preferredEntry = entry;
_hidden = NSRunningApplication.currentApplication.isHidden;
_overrideSequence = [overrdieSequence copy];
if(!targetApplication) {
_pid = -1;
_windowTitle = @"";
_windowId = -1;
}
else {
NSDictionary *frontApplicationInfoDict = targetApplication.mp_infoDictionary;
_pid = [frontApplicationInfoDict[MPProcessIdentifierKey] intValue];
_windowTitle = frontApplicationInfoDict[MPWindowTitleKey];
_windowId = (CGWindowID)[frontApplicationInfoDict[MPWindowIDKey] integerValue];
/* if we have any resolvers, let them provide the window title */
NSArray *resolvers = [MPPluginHost.sharedHost windowTitleResolverForRunningApplication:targetApplication];
@@ -41,7 +45,7 @@
}
}
}
_hidden = NSRunningApplication.currentApplication.isHidden;
}
return self;
}

View File

@@ -51,9 +51,9 @@
}
- (void)execute {
if([self.pasteData length] > 0) {
if(self.pasteData.length > 0) {
[MPPasteBoardController.defaultController stashObjects];
[MPPasteBoardController.defaultController copyObjectsWithoutTimeout:@[self.pasteData]];
[MPPasteBoardController.defaultController copyObjectWithoutTimeout:self.pasteData];
[MPKeyTyper sendPaste];
usleep(0.2 * NSEC_PER_MSEC); // on 10.10 we need to wait a bit before restoring the pasteboard contents
[MPPasteBoardController.defaultController restoreObjects];

View File

@@ -40,4 +40,11 @@ FOUNDATION_EXPORT NSString *const MPPluginUTI;
FOUNDATION_EXPORT NSString *const MPBundleHelpURLKey;
FOUNDATION_EXPORT NSString *const MPBundlePluginRepositoryURLKey;
FOUNDATION_EXPORT NSString *const MPPluginCompatibilityURLKey;
/**
Keychain Keys
*/
extern NSString *const TouchIdUnlockPublicKeyTag;
extern NSString *const TouchIdUnlockPrivateKeyTag;
#endif

View File

@@ -31,3 +31,6 @@ NSString *const MPBundleHelpURLKey = @"MPHelpURL";
NSString *const MPBundlePluginRepositoryURLKey = @"MPPluginRepositoryURL";
NSString *const MPPluginCompatibilityURLKey = @"MPPluginCompatibilityURLKey";
NSString *const TouchIdUnlockPublicKeyTag = @"com.hicknhacksoftware.macpass.publickey";
NSString *const TouchIdUnlockPrivateKeyTag = @"com.hicknhacksoftware.macpass.privatekey";

View File

@@ -31,7 +31,6 @@ typedef NS_ENUM(NSUInteger, MPContextButtonSegment) {
};
@property (nonatomic, strong) NSMenu *contextMenu;
- (void)setImage:(NSImage *)image;
@property (nonatomic, strong) NSImage *image;
@end

View File

@@ -91,6 +91,10 @@
[self setImage:image forSegment:MPContextButtonSegmentButton];
}
- (NSImage *)image {
return [self imageForSegment:MPContextButtonSegmentButton];
}
- (void)showContextMenu:(id)sender {
NSPoint point = self.frame.origin;
point.x = [self.cell widthForSegment:MPContextButtonSegmentButton];
@@ -102,15 +106,15 @@
NSImageRep *rep = [[self imageForSegment:MPContextButtonSegmentButton] bestRepresentationForRect:NSMakeRect(0, 0, 100, 100) context:nil hints:nil];
CGFloat scale = rep.size.width / rep.size.height;
switch (controlSize) {
case NSRegularControlSize:
case NSControlSizeRegular:
[self imageForSegment:MPContextButtonSegmentButton].size = NSMakeSize(16 * scale, 16);
break;
case NSSmallControlSize:
case NSControlSizeSmall:
[self imageForSegment:MPContextButtonSegmentButton].size = NSMakeSize(14 * scale, 14);
break;
case NSMiniControlSize:
case NSControlSizeMini:
[self imageForSegment:MPContextButtonSegmentButton].size = NSMakeSize(8 * scale, 8);
default:

View File

@@ -84,7 +84,7 @@ static void MPContextmenuHelperBeginSection(NSMutableArray *items) {
NSMenuItem *emptyTrash = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"EMPTY_TRASH", @"Menu item to empty the trash")
action:[MPActionHelper actionOfType:MPActionEmptyTrash]
keyEquivalent:@""];
emptyTrash.keyEquivalentModifierMask = (NSShiftKeyMask | NSCommandKeyMask);
emptyTrash.keyEquivalentModifierMask = (NSEventModifierFlagShift | NSEventModifierFlagCommand);
unichar backSpace = NSBackspaceCharacter;
emptyTrash.keyEquivalent = [NSString stringWithCharacters:&backSpace length:1];
[items addObject:emptyTrash];
@@ -99,7 +99,7 @@ static void MPContextmenuHelperBeginSection(NSMutableArray *items) {
NSMenuItem *copyPassword = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"COPY_PASSWORD", @"Menu item to copy the password of an entry")
action:[MPActionHelper actionOfType:MPActionCopyPassword]
keyEquivalent:@"c"];
copyPassword.keyEquivalentModifierMask = (copyPassword.keyEquivalentModifierMask | NSAlternateKeyMask);
copyPassword.keyEquivalentModifierMask = (copyPassword.keyEquivalentModifierMask | NSEventModifierFlagOption);
NSMenu *urlMenu = [[NSMenu alloc] init];
NSMenuItem *urlItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"URL", @"Submenu with options what to do with the URL of an entry")
action:0
@@ -129,7 +129,7 @@ static void MPContextmenuHelperBeginSection(NSMutableArray *items) {
NSMenuItem *showHistory = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"SHOW_HISTORY", @"Menu item to show the history of the selected entry")
action:[MPActionHelper actionOfType:MPActionShowEntryHistory]
keyEquivalent:@"h"];
showHistory.keyEquivalentModifierMask = (showHistory.keyEquivalentModifierMask | NSCommandKeyMask | NSControlKeyMask);
showHistory.keyEquivalentModifierMask = (showHistory.keyEquivalentModifierMask | NSEventModifierFlagCommand | NSEventModifierFlagControl);
[items addObject:showHistory];
}
if(insertShowGroupInOutline) {

View File

@@ -1,27 +0,0 @@
//
// MPCustomFieldTableView.h
// MacPass
//
// Created by Michael Starke on 11.09.18.
// Copyright © 2018 HicknHack Software GmbH. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
//
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
#import <Cocoa/Cocoa.h>
@interface MPCustomFieldTableView : NSTableView
@end

View File

@@ -1,40 +0,0 @@
//
// MPCustomFieldTableView.m
// MacPass
//
// Created by Michael Starke on 11.09.18.
// Copyright © 2018 HicknHack Software GmbH. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
//
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
#import "MPCustomFieldTableView.h"
@implementation MPCustomFieldTableView
/*
on macOS 10.11 and lower, the height is not calculated correctly
*/
- (NSSize)intrinsicContentSize {
if(@available(macOS 10.12, *)) {
return [super intrinsicContentSize];
}
if(self.numberOfRows > 0) {
return NSMakeSize(-1, self.numberOfRows * self.rowHeight);
}
return NSMakeSize(-1, -1);
}
@end

View File

@@ -38,25 +38,6 @@ NSInteger MPCustomFieldTagFromIndex(NSInteger index) {
@implementation MPCustomFieldTableViewDelegate
- (void)tableView:(NSTableView *)tableView didRemoveRowView:(NSTableRowView *)rowView forRow:(NSInteger)row {
if(@available(macOS 10.12, *)) {
// 10.12 and higher are working correctly
}
else {
[tableView invalidateIntrinsicContentSize];
}
}
- (void)tableView:(NSTableView *)tableView didAddRowView:(NSTableRowView *)rowView forRow:(NSInteger)row {
if(@available(macOS 10.12, *)) {
// 10.12 and higher are working correctly
}
else {
[tableView invalidateIntrinsicContentSize];
}
}
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
MPCustomFieldTableCellView *view = [tableView makeViewWithIdentifier:@"SelectedCell" owner:tableView];

View File

@@ -92,7 +92,8 @@
}
self.cipherPopupButton.menu = cipherMenu;
self.keyDerivationSettingsTabView.tabViewItems[0].identifier = [KPKAESKeyDerivation uuid];
self.keyDerivationSettingsTabView.tabViewItems[1].identifier = [KPKArgon2KeyDerivation uuid];
self.keyDerivationSettingsTabView.tabViewItems[1].identifier = [KPKArgon2DKeyDerivation uuid];
self.keyDerivationSettingsTabView.tabViewItems[2].identifier = [KPKArgon2IDKeyDerivation uuid];
}
#pragma mark Actions
@@ -164,7 +165,8 @@
metaData.cipherUUID = self.cipherPopupButton.selectedItem.representedObject;
KPKAESKeyDerivation *aesKdf = [[KPKAESKeyDerivation alloc] initWithParameters:[KPKAESKeyDerivation defaultParameters]];
KPKArgon2KeyDerivation *argon2Kdf = [[KPKArgon2KeyDerivation alloc] initWithParameters:[KPKArgon2KeyDerivation defaultParameters]];
KPKArgon2DKeyDerivation *argon2Kdf = [[KPKArgon2DKeyDerivation alloc] initWithParameters:[KPKArgon2DKeyDerivation defaultParameters]];
// FIXME: add Argon2id support!
NSUUID *selectedKdfUUID = self.keyDerivationSettingsTabView.selectedTabViewItem.identifier;
@@ -273,19 +275,21 @@
[self.keyDerivationPopupButton selectItemAtIndex:kdfIndex];
[self.keyDerivationSettingsTabView selectTabViewItemWithIdentifier:keyDerivation.uuid];
if([keyDerivation isKindOfClass:[KPKAESKeyDerivation class]]) {
if([keyDerivation isMemberOfClass:KPKAESKeyDerivation.class]) {
/* set to database values */
KPKAESKeyDerivation *aesKdf = (KPKAESKeyDerivation *)keyDerivation;
self.aesEncryptionRoundsTextField.integerValue = aesKdf.rounds;
self.createKeyDerivationParametersButton.enabled = YES;
/* fill defaults for Argon2 */
KPKArgon2KeyDerivation *argon2Kdf = [[KPKArgon2KeyDerivation alloc] initWithParameters:[KPKArgon2KeyDerivation defaultParameters]];
KPKArgon2DKeyDerivation *argon2Kdf = [[KPKArgon2DKeyDerivation alloc] initWithParameters:[KPKArgon2DKeyDerivation defaultParameters]];
self.argon2IterationsTextField.integerValue = argon2Kdf.iterations;
self.argon2Memory = argon2Kdf.memory;
self.argon2ThreadsTextField.integerValue = argon2Kdf.threads;
}
else if([keyDerivation isKindOfClass:[KPKArgon2KeyDerivation class]]) {
KPKArgon2KeyDerivation *argon2Kdf = (KPKArgon2KeyDerivation *)keyDerivation;
else if([keyDerivation isMemberOfClass:KPKArgon2DKeyDerivation.class]) {
/* set to database value */
KPKArgon2DKeyDerivation *argon2Kdf = (KPKArgon2DKeyDerivation *)keyDerivation;
self.argon2Memory = argon2Kdf.memory;
self.argon2ThreadsTextField.integerValue = argon2Kdf.threads;
self.argon2IterationsTextField.integerValue = argon2Kdf.iterations;
@@ -294,6 +298,9 @@
KPKAESKeyDerivation *aesKdf = [[KPKAESKeyDerivation alloc] initWithParameters:[KPKAESKeyDerivation defaultParameters]];
self.aesEncryptionRoundsTextField.integerValue = aesKdf.rounds;
}
else if([keyDerivation isMemberOfClass:KPKArgon2IDKeyDerivation.class]) {
// TODO: implement setup!
}
else {
NSAssert(NO, @"Unkown key derivation");
}

View File

@@ -44,7 +44,9 @@ NSString *const kMPDocumentSearchResultsKey = @"kMPDocumentSearchResul
self.searchContext = context;
[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(updateSearch:) name:NSUndoManagerDidRedoChangeNotification object:self.undoManager];
[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(updateSearch:) name:NSUndoManagerDidUndoChangeNotification object:self.undoManager];
//[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(updateSearch:) name:NSUndoManagerDidCloseUndoGroupNotification object:self.undoManager];
/* Do not do this since it seems to break the undo/redo grouping completly!
[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(updateSearch:) name:NSUndoManagerDidCloseUndoGroupNotification object:self.undoManager];
*/
[NSNotificationCenter.defaultCenter postNotificationName:MPDocumentDidEnterSearchNotification object:self];
[self updateSearch:self];
}
@@ -74,7 +76,9 @@ NSString *const kMPDocumentSearchResultsKey = @"kMPDocumentSearchResul
- (void)exitSearch:(id)sender {
[NSNotificationCenter.defaultCenter removeObserver:self name:NSUndoManagerDidUndoChangeNotification object:self.undoManager];
[NSNotificationCenter.defaultCenter removeObserver:self name:NSUndoManagerDidRedoChangeNotification object:self.undoManager];
//[NSNotificationCenter.defaultCenter removeObserver:self name:NSUndoManagerDidCloseUndoGroupNotification object:self.undoManager];
/* No need to do this since we did not register in the first place see [MPDocument enterSearchWithContext:]
[NSNotificationCenter.defaultCenter removeObserver:self name:NSUndoManagerDidCloseUndoGroupNotification object:self.undoManager];
*/
self.searchContext = nil;
[NSNotificationCenter.defaultCenter postNotificationName:MPDocumentDidExitSearchNotification object:self];
}
@@ -98,15 +102,15 @@ NSString *const kMPDocumentSearchResultsKey = @"kMPDocumentSearchResul
NSAssert([sender isKindOfClass:NSMenuItem.class], @"Internal inconsitency. Did expect NSMenuItem expected, but got %@", [sender class]);
state = ((NSMenuItem *)sender).state;
/* Manually toggle the state since the popupbuttoncell doesn't do it like we want it to */
state = state == NSOnState ? NSOffState : NSOnState;
state = state == NSControlStateValueOn ? NSControlStateValueOff : NSControlStateValueOn;
}
switch(state) {
case NSOffState:
case NSControlStateValueOff:
toggleFlag ^= MPEntrySearchAllCombineableFlags;
newFlags = isSingleFlag ? MPEntrySearchNone : (self.searchContext.searchFlags & toggleFlag);
break;
case NSOnState:
case NSControlStateValueOn:
if(isSingleFlag ) {
newFlags = toggleFlag; // This has to be either expired or double passwords
}

View File

@@ -39,7 +39,7 @@ FOUNDATION_EXPORT NSString *const MPDocumentDidAddGroupNotification;
* The userInfo dictionary contains the added entry at MPDocumentEntryKey
*/
FOUNDATION_EXPORT NSString *const MPDocumentDidAddEntryNotification;
FOUNDATION_EXPORT NSString *const MPDocumentDidRevertNotifiation;
FOUNDATION_EXPORT NSString *const MPDocumentDidRevertNotification;
FOUNDATION_EXPORT NSString *const MPDocumentDidLockDatabaseNotification;
FOUNDATION_EXPORT NSString *const MPDocumentDidUnlockDatabaseNotification;
@@ -108,13 +108,13 @@ FOUNDATION_EXPORT NSString *const MPDocumentGroupKey;
/**
* Decrypts the database with the given password and keyfile
*
* @param password The password to unlock the db with, can be nil. This is not the same as an empty string @""
* @param keyFileURL URL for the keyfile to use, can be nil
* @param compositeKey The CompositeKey to unlock the db.
* @param keyFileURL URL for the keyfile that was used to create the compositeKey. Can be nil.
* @param error Pointer to an NSError pointer of error reporting.
*
* @return YES if the document was unlocked sucessfully, NO otherwise. Consult the error object for details
*/
- (BOOL)unlockWithPassword:(NSString *)password keyFileURL:(NSURL *)keyFileURL error:(NSError *__autoreleasing*)error;
- (BOOL)unlockWithPassword:(KPKCompositeKey *)compositeKey keyFileURL:(NSURL *)keyFileURL error:(NSError *__autoreleasing*)error;
/**
* Changes the password of the database. Some sanity checks are applied and the change is aborted if the new values aren't valid
*

View File

@@ -45,7 +45,7 @@
NSString *const MPDocumentDidAddGroupNotification = @"com.hicknhack.macpass.MPDocumentDidAddGroupNotification";
NSString *const MPDocumentDidAddEntryNotification = @"com.hicknhack.macpass.MPDocumentDidAddEntryNotification";
NSString *const MPDocumentDidRevertNotifiation = @"com.hicknhack.macpass.MPDocumentDidRevertNotifiation";
NSString *const MPDocumentDidRevertNotification = @"com.hicknhack.macpass.MPDocumentDidRevertNotification";
NSString *const MPDocumentDidLockDatabaseNotification = @"com.hicknhack.macpass.MPDocumentDidLockDatabaseNotification";
NSString *const MPDocumentDidUnlockDatabaseNotification = @"com.hicknhack.macpass.MPDocumentDidUnlockDatabaseNotification";
@@ -147,6 +147,10 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGrou
[self addWindowController:windowController];
}
- (BOOL)canAsynchronouslyWriteToURL:(NSURL *)url ofType:(NSString *)typeName forSaveOperation:(NSSaveOperationType)saveOperation {
return YES;
}
- (BOOL)checkAutosavingSafetyAndReturnError:(NSError **)outError {
if(![super checkAutosavingSafetyAndReturnError:outError]) {
return NO; // default checking has found an error!
@@ -155,7 +159,7 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGrou
if(self.encryptedData) {
return YES;
}
if(self.compositeKey.hasPasswordOrKeyFile) {
if(self.compositeKey.hasKeys) {
return YES; // key is set, so autosave should be save
}
@@ -186,7 +190,7 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGrou
NSLog(@"%@ should not be called on locked databases!", NSStringFromSelector(_cmd));
return self.encryptedData;
}
if(!self.compositeKey.hasPasswordOrKeyFile) {
if(!self.compositeKey.hasKeys) {
if(outError != NULL) {
NSDictionary *userInfo = @{ NSLocalizedDescriptionKey: NSLocalizedString(@"WARNING_ON_SAVE_NO_PASSWORD_OR_KEY_SET", "") };
*outError = [NSError errorWithDomain:MPDefaultErrorDomain code:0 userInfo:userInfo];
@@ -202,7 +206,15 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGrou
}
return nil; // We do not know what version to save!
}
return [self.tree encryptWithKey:self.compositeKey format:format error:outError];
// create a copy to allow for unblocking user interaction
NSLog(@"Copying tree to save…");
KPKTree *copy = [self.tree copy];
NSLog(@"Created copy…");
[self unblockUserInteraction];
NSLog(@"Starting encryption…");
NSData *data = [copy encryptWithKey:self.compositeKey format:format error:outError];
NSLog(@"Finished encryption…");
return data;
}
- (BOOL)readFromURL:(NSURL *)url ofType:(NSString *)typeName error:(NSError **)outError {
@@ -216,7 +228,7 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGrou
- (BOOL)revertToContentsOfURL:(NSURL *)absoluteURL ofType:(NSString *)typeName error:(NSError **)outError {
if([super revertToContentsOfURL:absoluteURL ofType:typeName error:outError]) {
[[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentDidRevertNotifiation object:self];
[[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentDidRevertNotification object:self];
return YES;
}
return NO;
@@ -295,7 +307,7 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGrou
return;
}
NSAlert *alert = [[NSAlert alloc] init];
alert.alertStyle = NSWarningAlertStyle;
alert.alertStyle = NSAlertStyleWarning;
alert.messageText = NSLocalizedString(@"FILE_CHANGED_BY_OTHERS_MESSAGE_TEXT", @"Message displayed when an open file was changed from another application");
alert.informativeText = NSLocalizedString(@"FILE_CHANGED_BY_OTHERS_INFO_TEXT", @"Informative text displayed when the file was change from another application");
alert.showsSuppressionButton = YES;
@@ -369,7 +381,7 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGrou
if(mergeKDB) {
NSAlert *alert = [[NSAlert alloc] init];
alert.alertStyle = NSWarningAlertStyle;
alert.alertStyle = NSAlertStyleWarning;
alert.messageText = NSLocalizedString(@"ALERT_MERGE_KDB_FILE_MESSAGE", @"Alert message warning user about KDB file merge");
alert.informativeText = NSLocalizedString(@"ALERT_MERGE_KDB_FILE_INFO_TEXT", @"Informative text displayed when merging KDB files");
[alert addButtonWithTitle:NSLocalizedString(@"ALERT_MERGE_CONTINUE", @"Button in dialog to merge KDB changes into file!")];
@@ -417,11 +429,9 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGrou
MPPasswordInputController *passwordInputController = [[MPPasswordInputController alloc] init];
[passwordInputController requestPasswordWithMessage:NSLocalizedString(@"EXTERN_CHANGE_OF_MASTERKEY", @"The master key was changed by an external program!")
cancelLabel:NSLocalizedString(@"ABORT_MERGE_KEEP_MINE", @"Button label to abort a merge on a file with changed master key!")
completionHandler:^BOOL(NSString *password, NSURL *keyURL, BOOL didCancel, NSError *__autoreleasing *error) {
completionHandler:^BOOL(KPKCompositeKey *compositeKey, NSURL* keyURL, BOOL didCancel, NSError *__autoreleasing *error) {
[self.windowForSheet endSheet:sheet returnCode:(didCancel ? NSModalResponseCancel : NSModalResponseOK)];
if(!didCancel) {
NSData *keyFileData = keyURL ? [NSData dataWithContentsOfURL:keyURL] : nil;
KPKCompositeKey *compositeKey = [[KPKCompositeKey alloc] initWithPassword:password keyFileData:keyFileData];
[self _mergeWithContentsFromURL:url key:compositeKey options:options];
}
// just return yes regardless since we will display the sheet again if needed!
@@ -487,10 +497,9 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGrou
}
- (BOOL)unlockWithPassword:(NSString *)password keyFileURL:(NSURL *)keyFileURL error:(NSError *__autoreleasing*)error{
- (BOOL)unlockWithPassword:(KPKCompositeKey *)compositeKey keyFileURL:(NSURL *)keyFileURL error:(NSError *__autoreleasing*)error{
// TODO: Make this API asynchronous
NSData *keyFileData = keyFileURL ? [NSData dataWithContentsOfURL:keyFileURL] : nil;
self.compositeKey = [[KPKCompositeKey alloc] initWithPassword:password keyFileData:keyFileData];
self.compositeKey = compositeKey;
self.tree = [[KPKTree alloc] initWithData:self.encryptedData key:self.compositeKey error:error];
BOOL isUnlocked = (nil != self.tree);
@@ -510,17 +519,15 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGrou
- (BOOL)changePassword:(NSString *)password keyFileURL:(NSURL *)keyFileURL {
/* sanity check? */
if([password length] == 0 && keyFileURL == nil) {
if(password.length == 0 && keyFileURL == nil) {
return NO;
}
NSData *keyFileData = keyFileURL ? [NSData dataWithContentsOfURL:keyFileURL] : nil;
if(!self.compositeKey) {
self.compositeKey = [[KPKCompositeKey alloc] initWithPassword:password keyFileData:keyFileData];
}
else {
[self.compositeKey setPassword:password andKeyFileData:keyFileData];
}
self.tree.metaData.masterKeyChanged = [NSDate date];
self.compositeKey = [[KPKCompositeKey alloc] init];
[self.compositeKey addKey:[KPKKey keyWithPassword:password]];
[self.compositeKey addKey:[KPKKey keyWithKeyFileData:keyFileData]];
self.tree.metaData.masterKeyChanged = NSDate.date;
/* Key change is not undoable so just recored the change as done */
[self updateChangeCount:NSChangeDone];
/*
@@ -672,9 +679,14 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGrou
if([self.tree.metaData.defaultUserName length] > 0) {
newEntry.username = self.tree.metaData.defaultUserName;
}
NSString *defaultPassword = [NSString passwordWithDefaultSettings];
if(defaultPassword) {
newEntry.password = defaultPassword;
/* only generate passwords for new entries, if set */
BOOL generatePassword = [NSUserDefaults.standardUserDefaults boolForKey:kMPSettingsKeyGeneratePasswordForNewEntires];
if(generatePassword) {
NSString *defaultPassword = [NSString passwordWithDefaultSettings];
if(defaultPassword) {
newEntry.password = defaultPassword;
}
}
/* re-enable undo/redo if we did turn it off */
if(wasUndoEnabeld) {
@@ -751,7 +763,7 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGrou
#pragma mark Actions
- (void)emptyTrash:(id)sender {
NSAlert *alert = [[NSAlert alloc] init];
alert.alertStyle = NSWarningAlertStyle;
alert.alertStyle = NSAlertStyleWarning;
alert.messageText = NSLocalizedString(@"WARNING_ON_EMPTY_TRASH_TITLE", "Message text for the alert displayed when clearing the Trash");
alert.informativeText = NSLocalizedString(@"WARNING_ON_EMPTY_TRASH_DESCRIPTION", "Informative Text displayed when clearing the Trash");
@@ -770,7 +782,7 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGrou
KPKEntry *entry = node.asEntry;
NSAlert *alert = [[NSAlert alloc] init];
alert.alertStyle = NSWarningAlertStyle;
alert.alertStyle = NSAlertStyleWarning;
alert.messageText = NSLocalizedString(@"WARNING_ON_DELETE_TRASHED_NODE_TITLE", "Message text for the alert displayed when deleting a node");
alert.informativeText = NSLocalizedString(@"WARNING_ON_DELETE_TRASHED_NODE_DESCRIPTION", "Informative Text displayed when clearing the Trash");
@@ -832,13 +844,20 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGrou
}
- (void)duplicateEntryWithOptions:(KPKCopyOptions)options {
KPKEntry *duplicate;
for(KPKEntry *entry in self.selectedEntries) {
KPKEntry *duplicate = [entry copyWithTitle:nil options:options];
duplicate = [entry copyWithTitle:nil options:options];
[duplicate addToGroup:entry.parent];
}
[self.undoManager setActionName:[NSString stringWithFormat:NSLocalizedString(@"DUPLICATE_ENTRIES_ACTION_NAME", @"Action name for duplicating entries"), self.selectedEntries.count]];
if(duplicate) {
[NSNotificationCenter.defaultCenter postNotificationName:MPDocumentDidAddEntryNotification
object:self
userInfo:@{ MPDocumentEntryKey: duplicate }];
}
}
- (void)duplicateGroup:(id)sender {
for(KPKGroup *group in self.selectedGroups) {
KPKGroup *duplicate = [group copyWithTitle:nil options:kKPKCopyOptionNone];
@@ -952,7 +971,7 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGrou
/* user has removed the keyfile or we should not safe it so remove it */
[keysForFiles removeObjectForKey:self.fileURL.path.sha1HexDigest];
}
else if(self.compositeKey.hasPassword && self.compositeKey.hasKeyFile) {
else if([self.compositeKey hasKeyOfClass:KPKPasswordKey.class] && [self.compositeKey hasKeyOfClass:KPKFileKey.class]) {
if(nil == keysForFiles) {
keysForFiles = [[NSMutableDictionary alloc] initWithCapacity:1];
}

View File

@@ -105,7 +105,7 @@
NSAlert *alert = [[NSAlert alloc] init];
alert.messageText = NSLocalizedString(@"FILE_OPEN_ERROR", "Error while reopening last known documents");
alert.informativeText = error.localizedDescription;
alert.alertStyle = NSCriticalAlertStyle;
alert.alertStyle = NSAlertStyleCritical;
[alert runModal];
}

View File

@@ -0,0 +1,30 @@
//
// MPDocumentSplitViewController.h
// MacPass
//
// Created by Michael Starke on 31.01.20.
// Copyright © 2020 HicknHack Software GmbH. All rights reserved.
//
#import <Cocoa/Cocoa.h>
NS_ASSUME_NONNULL_BEGIN
@class MPEntryViewController;
@class MPInspectorViewController;
@class MPOutlineViewController;
@class MPDocument;
@interface MPDocumentSplitViewController : NSSplitViewController
@property (readonly, strong) MPEntryViewController *entryViewController;
@property (readonly, strong) MPOutlineViewController *outlineViewController;
@property (readonly, strong) MPInspectorViewController *inspectorViewController;
- (void)registerNotificationsForDocument:(MPDocument *)document;
- (IBAction)toggleInspector:(id)sender;
- (void)showOutline;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,109 @@
//
// MPDocumentSplitViewController.m
// MacPass
//
// Created by Michael Starke on 31.01.20.
// Copyright © 2020 HicknHack Software GmbH. All rights reserved.
//
#import "MPDocumentSplitViewController.h"
#import "MPOutlineViewController.h"
#import "MPEntryViewController.h"
#import "MPInspectorViewController.h"
#import "MPSettingsHelper.h"
@interface MPDocumentSplitViewController ()
@property (strong) MPEntryViewController *entryViewController;
@property (strong) MPOutlineViewController *outlineViewController;
@property (strong) MPInspectorViewController *inspectorViewController;
@end
@implementation MPDocumentSplitViewController
- (NSNibName)nibName {
return @"DocumentSplitView";
}
- (instancetype)initWithNibName:(NSNibName)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if(self) {
_outlineViewController = [[MPOutlineViewController alloc] init];
_entryViewController = [[MPEntryViewController alloc] init];
_inspectorViewController = [[MPInspectorViewController alloc] init];
}
return self;
}
- (void)viewWillLayout {
self.splitView.autosaveName = @"SplitView";
[super viewWillLayout];
}
/*- (void)updateViewConstraints {
[super updateViewConstraints];
if(self.inspectorTopEdgeConstraint) {
if(!self.inspectorTopEdgeConstraint.isActive) {
self.inspectorTopEdgeConstraint.active = YES;
}
return; // everything is set up.
}
// setup the constraint if needed
NSWindow *window = self.view.window;
if(!window) {
return;
}
NSSplitViewItem *inspector = [self splitViewItemForViewController:self.inspectorViewController];
NSSplitViewItem *entries = [self splitViewItemForViewController:self.entryViewController];
NSSplitViewItem *outline = [self splitViewItemForViewController:self.outlineViewController];
[inspector.viewController.view.topAnchor constraintEqualToAnchor:[window.contentLayoutGuide topAnchor]].active = YES;
[entries.viewController.view.topAnchor constraintEqualToAnchor:[window.contentLayoutGuide topAnchor]].active = YES;
[outline.viewController.view.topAnchor constraintEqualToAnchor:[window.contentLayoutGuide topAnchor]].active = YES;
}*/
- (void)viewDidLoad {
[super viewDidLoad];
self.splitView.translatesAutoresizingMaskIntoConstraints = NO;
NSSplitViewItem *outlineItem = [NSSplitViewItem sidebarWithViewController:self.outlineViewController];
outlineItem.holdingPriority = NSLayoutPriorityDefaultLow + 2;
outlineItem.canCollapse = NO;
outlineItem.minimumThickness = 150;
NSSplitViewItem *entries = [NSSplitViewItem splitViewItemWithViewController:self.entryViewController];
entries.canCollapse = NO;
entries.minimumThickness = 150;
NSSplitViewItem *inspector = [NSSplitViewItem splitViewItemWithViewController:self.inspectorViewController];
inspector.canCollapse = YES;
inspector.minimumThickness = 200;
inspector.holdingPriority = NSLayoutPriorityDefaultLow + 1;
[self addSplitViewItem:outlineItem];
[self addSplitViewItem:entries];
[self addSplitViewItem:inspector];
BOOL showInspector = [NSUserDefaults.standardUserDefaults boolForKey:kMPSettingsKeyShowInspector];
inspector.collapsed = !showInspector;
}
- (void)registerNotificationsForDocument:(MPDocument *)document {
[self.entryViewController registerNotificationsForDocument:document];
[self.outlineViewController registerNotificationsForDocument:document];
[self.inspectorViewController registerNotificationsForDocument:document];
}
- (void)showOutline {
// FIXME: do not require this to be called directly
[self.outlineViewController showOutline];
}
- (void)toggleInspector:(id)sender {
NSSplitViewItem *inspector = [self splitViewItemForViewController:self.inspectorViewController];
inspector.collapsed = !inspector.collapsed;
[NSUserDefaults.standardUserDefaults setBool:!inspector.collapsed forKey:kMPSettingsKeyShowInspector];
}
@end

View File

@@ -34,9 +34,6 @@
@interface MPDocumentWindowController : NSWindowController <NSTouchBarDelegate>
@property (readonly, strong) MPPasswordInputController *passwordInputController;
@property (readonly, strong) MPEntryViewController *entryViewController;
@property (readonly, strong) MPOutlineViewController *outlineViewController;
@property (readonly, strong) MPInspectorViewController *inspectorViewController;
@property (readonly, strong) MPToolbarDelegate *toolbarDelegate;
@property (readonly, nonatomic, strong) NSSearchField *searchField;

View File

@@ -29,6 +29,7 @@
#import "MPDatabaseSettingsWindowController.h"
#import "MPDocument.h"
#import "MPDocumentWindowDelegate.h"
#import "MPDocumentSplitViewController.h"
#import "MPDuplicateEntryOptionsWindowController.h"
#import "MPEntryViewController.h"
#import "MPFixAutotypeWindowController.h"
@@ -58,14 +59,11 @@ typedef void (^MPPasswordChangedBlock)(BOOL didChangePassword);
id _firstResponder;
}
@property (strong) IBOutlet NSSplitView *splitView;
@property (strong) NSToolbar *toolbar;
@property (strong) MPPasswordInputController *passwordInputController;
@property (strong) MPEntryViewController *entryViewController;
@property (strong) MPOutlineViewController *outlineViewController;
@property (strong) MPInspectorViewController *inspectorViewController;
@property (strong) MPDocumentSplitViewController *splitViewController;
@property (strong) MPDatabaseSettingsWindowController *documentSettingsWindowController;
@property (strong) MPDocumentWindowDelegate *documentWindowDelegate;
@property (strong) MPPasswordEditWindowController *passwordEditWindowController;
@@ -87,9 +85,7 @@ typedef void (^MPPasswordChangedBlock)(BOOL didChangePassword);
if( self ) {
_firstResponder = nil;
_toolbarDelegate = [[MPToolbarDelegate alloc] init];
_outlineViewController = [[MPOutlineViewController alloc] init];
_entryViewController = [[MPEntryViewController alloc] init];
_inspectorViewController = [[MPInspectorViewController alloc] init];
_splitViewController = [[MPDocumentSplitViewController alloc] init];
_documentWindowDelegate = [[MPDocumentWindowDelegate alloc] init];
}
return self;
@@ -104,24 +100,27 @@ typedef void (^MPPasswordChangedBlock)(BOOL didChangePassword);
[super windowDidLoad];
self.window.delegate = self.documentWindowDelegate;
//self.window.styleMask |= NSWindowStyleMaskFullSizeContentView;
if (@available(macOS 11.0, *)) {
self.window.toolbarStyle = NSWindowToolbarStyleExpanded;
}
[self.window registerForDraggedTypes:@[NSURLPboardType]];
MPDocument *document = self.document;
[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(_didRevertDocument:) name:MPDocumentDidRevertNotifiation object:document];
[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(_didRevertDocument:) name:MPDocumentDidRevertNotification object:document];
[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(_didUnlockDatabase:) name:MPDocumentDidUnlockDatabaseNotification object:document];
[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(_didAddEntry:) name:MPDocumentDidAddEntryNotification object:document];
[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(_didAddGroup:) name:MPDocumentDidAddGroupNotification object:document];
[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(_didLockDatabase:) name:MPDocumentDidLockDatabaseNotification object:document];
[self.entryViewController registerNotificationsForDocument:document];
[self.inspectorViewController registerNotificationsForDocument:document];
[self.outlineViewController registerNotificationsForDocument:document];
[self.splitViewController registerNotificationsForDocument:document];
[self.toolbarDelegate registerNotificationsForDocument:document];
self.toolbar = [[NSToolbar alloc] initWithIdentifier:@"MainWindowToolbar"];
self.toolbar.autosavesConfiguration = YES;
self.toolbar.allowsUserCustomization = YES;
/* center search in toolbar */
if (@available(macOS 10.14, *)) {
self.toolbar.centeredItemIdentifier = MPToolbarItemIdentifierSearch;
} else {
@@ -131,23 +130,6 @@ typedef void (^MPPasswordChangedBlock)(BOOL didChangePassword);
self.window.toolbar = self.toolbar;
self.toolbarDelegate.toolbar = self.toolbar;
self.splitView.translatesAutoresizingMaskIntoConstraints = NO;
NSView *outlineView = self.outlineViewController.view;
NSView *inspectorView = self.inspectorViewController.view;
NSView *entryView = self.entryViewController.view;
[self.splitView addSubview:outlineView];
[self.splitView addSubview:entryView];
[self.splitView addSubview:inspectorView];
[self.splitView setHoldingPriority:NSLayoutPriorityDefaultLow+2 forSubviewAtIndex:0];
[self.splitView setHoldingPriority:NSLayoutPriorityDefaultLow+1 forSubviewAtIndex:2];
BOOL showInspector = [NSUserDefaults.standardUserDefaults boolForKey:kMPSettingsKeyShowInspector];
if(!showInspector) {
[inspectorView removeFromSuperview];
}
if(document.encrypted) {
[self showPasswordInput];
}
@@ -155,8 +137,6 @@ typedef void (^MPPasswordChangedBlock)(BOOL didChangePassword);
[self showEntries];
}
self.splitView.autosaveName = @"SplitView";
/*
TODO: Add display for database color?
NSTitlebarAccessoryViewController *tbc = [[MPTitlebarColorAccessoryViewController alloc] init];
@@ -169,40 +149,21 @@ typedef void (^MPPasswordChangedBlock)(BOOL didChangePassword);
return self.toolbarDelegate.searchField;
}
- (void)_setContentViewController:(MPViewController *)viewController {
NSView *newContentView = nil;
if(viewController && viewController.view) {
newContentView = viewController.view;
- (void)setContentViewController:(NSViewController *)contentViewController {
contentViewController.view.frame = self.window.contentView.frame;
[super setContentViewController:contentViewController];
if([contentViewController isKindOfClass:MPViewController.class]) {
/* enqueue async into main to catch some cases, where the UI would not set the responder correctly */
MPDocumentWindowController * __weak welf = self;
dispatch_async(dispatch_get_main_queue(), ^{
NSResponder *responder = ((MPViewController *)contentViewController).reconmendedFirstResponder;
[welf.window makeFirstResponder:responder];
});
}
NSView *contentView = self.window.contentView;
NSView *oldSubView = nil;
if(contentView.subviews.count == 1) {
oldSubView = contentView.subviews.firstObject;
}
if(oldSubView == newContentView) {
return; // View is already present
}
[oldSubView removeFromSuperviewWithoutNeedingDisplay];
[contentView addSubview:newContentView];
[contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[newContentView]|"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(newContentView)]];
NSNumber *border = @([[self window] contentBorderThicknessForEdge:NSMinYEdge]);
[contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[newContentView]-border-|"
options:0
metrics:NSDictionaryOfVariableBindings(border)
views:NSDictionaryOfVariableBindings(newContentView)]];
[contentView layout];
[self.window makeFirstResponder:viewController.reconmendedFirstResponder];
}
#pragma mark MPDocument notifications
- (void)_didRevertDocument:(NSNotification *)notification {
[self.outlineViewController clearSelection];
[self showPasswordInput];
}
@@ -261,7 +222,7 @@ typedef void (^MPPasswordChangedBlock)(BOOL didChangePassword);
savePanel.allowedFileTypes = @[(id)kUTTypeXML];
savePanel.canSelectHiddenExtension = YES;
[savePanel beginSheetModalForWindow:self.window completionHandler:^(NSInteger result) {
if(result == NSFileHandlingPanelOKButton) {
if(result == NSModalResponseOK) {
[document writeXMLToURL:savePanel.URL];
}
}];
@@ -277,9 +238,9 @@ typedef void (^MPPasswordChangedBlock)(BOOL didChangePassword);
openPanel.prompt = NSLocalizedString(@"OPEN_BUTTON_IMPORT_XML_OPEN_PANEL", "Open button in the open panel to import an XML file");
openPanel.message = NSLocalizedString(@"MESSAGE_XML_OPEN_PANEL", "Message in the open panel to import an XML file");
[openPanel beginSheetModalForWindow:self.window completionHandler:^(NSInteger result) {
if(result == NSFileHandlingPanelOKButton) {
if(result == NSModalResponseOK) {
[document readXMLfromURL:openPanel.URL];
[self.outlineViewController showOutline];
[self.splitViewController showOutline];
}
}];
}
@@ -342,7 +303,7 @@ typedef void (^MPPasswordChangedBlock)(BOOL didChangePassword);
openPanel.message = NSLocalizedString(@"SELECT_FILE_TO_MERGE", @"Message for the dialog to open a file for merge");
//openPanel.allowedFileTypes = @[(id)kUTTypeXML];
[openPanel beginSheetModalForWindow:self.window completionHandler:^(NSInteger result) {
if(result == NSFileHandlingPanelOKButton) {
if(result == NSModalResponseOK) {
[document mergeWithContentsFromURL:openPanel.URL key:document.compositeKey];
}
}];
@@ -363,13 +324,12 @@ typedef void (^MPPasswordChangedBlock)(BOOL didChangePassword);
if(!self.passwordInputController) {
self.passwordInputController = [[MPPasswordInputController alloc] init];
}
[self _setContentViewController:self.passwordInputController];
[self.passwordInputController requestPasswordWithMessage:message cancelLabel:nil completionHandler:^BOOL(NSString *password, NSURL *keyURL, BOOL didCancel, NSError *__autoreleasing *error) {
self.contentViewController = self.passwordInputController;
[self.passwordInputController requestPasswordWithMessage:message cancelLabel:nil completionHandler:^BOOL(KPKCompositeKey* compositeKey, NSURL* keyURL, BOOL didCancel, NSError *__autoreleasing *error) {
if(didCancel) {
return NO;
}
return [((MPDocument *)self.document) unlockWithPassword:password keyFileURL:keyURL error:error];
return [((MPDocument *)self.document) unlockWithPassword:compositeKey keyFileURL:keyURL error:error ];
}];
}
@@ -469,27 +429,17 @@ typedef void (^MPPasswordChangedBlock)(BOOL didChangePassword);
}
- (void)pickExpiryDate:(id)sender {
[self.inspectorViewController pickExpiryDate:sender];
// FIXME: use propert responder chain
[self.splitViewController.inspectorViewController pickExpiryDate:sender];
}
- (void)showPluginData:(id)sender {
[self.inspectorViewController showPluginData:sender];
// FIXME: use propert responder chain
[self.splitViewController.inspectorViewController showPluginData:sender];
}
- (void)toggleInspector:(id)sender {
NSView *inspectorView = self.inspectorViewController.view;
BOOL inspectorWasVisible = [self _isInspectorVisible];
if(inspectorWasVisible) {
[inspectorView removeFromSuperview];
}
else {
[self.splitView addSubview:inspectorView];
[self.splitView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"[inspectorView(>=200)]"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(inspectorView)]];
}
[[NSUserDefaults standardUserDefaults] setBool:!inspectorWasVisible forKey:kMPSettingsKeyShowInspector];
[self.splitViewController toggleInspector:sender];
}
- (void)performAutotypeForEntry:(id)sender {
@@ -507,108 +457,58 @@ typedef void (^MPPasswordChangedBlock)(BOOL didChangePassword);
}
- (void)focusEntries:(id)sender {
[self.window makeFirstResponder:[self.entryViewController reconmendedFirstResponder]];
// FIXME: use propert responder chain
[self.window makeFirstResponder:[self.splitViewController.entryViewController reconmendedFirstResponder]];
}
- (void)focusGroups:(id)sender {
[self.window makeFirstResponder:[self.outlineViewController reconmendedFirstResponder]];
// FIXME: use propert responder chain
[self.window makeFirstResponder:[self.splitViewController.outlineViewController reconmendedFirstResponder]];
}
- (void)focusInspector:(id)sender {
[self.window makeFirstResponder:[self.inspectorViewController reconmendedFirstResponder]];
// FIXME: use propert responder chain
[self.window makeFirstResponder:[self.splitViewController.inspectorViewController reconmendedFirstResponder]];
}
- (void)showEntries {
NSView *contentView = self.window.contentView;
if(self.splitView == contentView) {
return; // We are displaying the entries already
}
if(contentView.subviews.count == 1) {
[contentView.subviews.firstObject removeFromSuperviewWithoutNeedingDisplay];
}
[contentView addSubview:self.splitView];
NSView *outlineView = self.outlineViewController.view;
NSView *inspectorView = self.inspectorViewController.view;
NSView *entryView = self.entryViewController.view;
self.contentViewController = self.splitViewController;
[self.splitViewController showOutline];
/*
The current easy way to prevent layout hiccups is to add the inspector
Add all needed constraints an then remove it again, if it was hidden
*/
BOOL removeInspector = NO;
if(!inspectorView.superview) {
[self.splitView addSubview:inspectorView];
removeInspector = YES;
}
/* Maybe we should consider not double adding constraints */
NSDictionary *views = NSDictionaryOfVariableBindings(outlineView, inspectorView, entryView, _splitView);
[self.splitView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[outlineView(>=150)]-1-[entryView(>=150)]-1-[inspectorView(>=200)]|"
options:0
metrics:nil
views:views]];
[self.splitView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[outlineView]|"
options:0
metrics:nil
views:views]];
[self.splitView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[entryView(>=200)]|"
options:0
metrics:nil
views:views]];
[self.splitView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[inspectorView]|"
options:0
metrics:nil
views:views]];
NSNumber *border = @([[self window] contentBorderThicknessForEdge:NSMinYEdge]);
[contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_splitView]-border-|"
options:0
metrics:NSDictionaryOfVariableBindings(border)
views:views]];
[contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_splitView]|"
options:0
metrics:nil
views:views]];
[self.outlineViewController showOutline];
/* Restore the State the inspector view was in before the view change */
if(removeInspector) {
[inspectorView removeFromSuperview];
}
[contentView layoutSubtreeIfNeeded];
}
- (void)showGroupInOutline:(id)sender {
NSArray<KPKEntry *> *targetEntries = self.entryViewController.currentTargetEntries;
NSArray<KPKEntry *> *targetEntries = self.splitViewController.entryViewController.currentTargetEntries;
if(targetEntries.count != 1) {
return;
}
[self.outlineViewController selectGroup:targetEntries.lastObject.parent];
[self.splitViewController.outlineViewController selectGroup:targetEntries.lastObject.parent];
}
#pragma mark -
#pragma mark Actions forwarded to MPEntryViewController
- (void)copyUsername:(id)sender {
[self.entryViewController copyUsername:sender];
[self.splitViewController.entryViewController copyUsername:sender];
}
- (void)copyPassword:(id)sender {
[self.entryViewController copyPassword:sender];
[self.splitViewController.entryViewController copyPassword:sender];
}
- (void)copyCustomAttribute:(id)sender {
[self.entryViewController copyCustomAttribute:sender];
[self.splitViewController.entryViewController copyCustomAttribute:sender];
}
- (void)copyAsReference:(id)sender {
[self.entryViewController copyAsReference:sender];
[self.splitViewController.entryViewController copyAsReference:sender];
}
- (void)copyURL:(id)sender {
[self.entryViewController copyURL:sender];
[self.splitViewController.entryViewController copyURL:sender];
}
- (void)openURL:(id)sender {
[self.entryViewController openURL:sender];
[self.splitViewController.entryViewController openURL:sender];
}
#pragma mark Validation
@@ -622,7 +522,7 @@ typedef void (^MPPasswordChangedBlock)(BOOL didChangePassword);
if(document.shouldEnforcePasswordChange) {
NSAlert *alert = [[NSAlert alloc] init];
alert.alertStyle = NSCriticalAlertStyle;
alert.alertStyle = NSAlertStyleCritical;
alert.messageText = NSLocalizedString(@"ENFORCE_PASSWORD_CHANGE_ALERT_TITLE", "Message text for the enforce password change alert");
alert.informativeText = NSLocalizedString(@"ENFORCE_PASSWORD_CHANGE_ALERT_DESCRIPTION", "Informative text for the enforce password change alert");
@@ -653,7 +553,7 @@ typedef void (^MPPasswordChangedBlock)(BOOL didChangePassword);
else if(document.shouldRecommendPasswordChange) {
NSAlert *alert = [[NSAlert alloc] init];
alert.alertStyle = NSInformationalAlertStyle;
alert.alertStyle = NSAlertStyleInformational;
alert.messageText = NSLocalizedString(@"RECOMMEND_PASSWORD_CHANGE_ALERT_TITLE", "Message text for the recommend password change alert");
alert.informativeText = NSLocalizedString(@"RECOMMEND_PASSWORD_CHANGE_ALERT_DESCRIPTION", "Informative text for the recommend password change alert");
@@ -690,8 +590,8 @@ typedef void (^MPPasswordChangedBlock)(BOOL didChangePassword);
#pragma mark UI Helper
- (BOOL)_isInspectorVisible {
NSView *inspectorView = self.inspectorViewController.view;
return (nil != inspectorView.superview);
NSSplitViewItem *item = [self.splitViewController splitViewItemForViewController:self.splitViewController.inspectorViewController];
return !item.isCollapsed;
}
- (NSTouchBar *)makeTouchBar {

View File

@@ -47,9 +47,8 @@
@property (weak) IBOutlet NSTokenField *tagsTokenField;
@property (weak) IBOutlet NSTextField *uuidTextField;
@property (weak) IBOutlet NSTextField *createdTextField;
@property (weak) IBOutlet NSTextField *modifiedTextField;
@property (weak) IBOutlet MPContextButton *addCustomFieldButton;
@property (strong) IBOutlet NSStackView *fieldsStackView;
/* Attachments */
@property (weak) IBOutlet NSButtonCell *addAttachmentButton;
@@ -60,6 +59,11 @@
@property (strong) IBOutlet NSTableView *customFieldsTableView;
@property (weak) IBOutlet NSButton *showCustomDataButton;
/* TOTP */
@property (strong) IBOutlet NSProgressIndicator *totpProgressIndicator;
@property (strong) IBOutlet NSTextField *totpLabelTextField;
@property (strong) IBOutlet NSTextField *totpCodeTextField;
/* Autotype */
@property (strong) IBOutlet NSView *autotypView;
@property (weak) IBOutlet NSButton *enableAutotypeCheckButton;
@@ -80,6 +84,7 @@
- (IBAction)showPasswordGenerator:(id)sender;
- (IBAction)showReferenceBuilder:(id)sender;
- (IBAction)showAutotypeBuilder:(id)sender;
- (IBAction)showOTPSetup:(id)sender;
- (IBAction)saveAttachment:(id)sender;
- (IBAction)addAttachment:(id)sender;
@@ -93,4 +98,5 @@
- (IBAction)toggleQuicklookPreview:(id)sender;
- (IBAction)toggleExpire:(NSButton*)sender;
@end

View File

@@ -31,6 +31,8 @@
#import "MPTagsTokenFieldDelegate.h"
#import "MPAutotypeBuilderViewController.h"
#import "MPReferenceBuilderViewController.h"
#import "MPTOTPViewController.h"
#import "MPTOTPSetupViewController.h"
#import "MPPrettyPasswordTransformer.h"
#import "NSString+MPPasswordCreation.h"
@@ -49,7 +51,6 @@
#import "MPArrayController.h"
#import "KeePassKit/KeePassKit.h"
#import "HNHUi/HNHUi.h"
typedef NS_ENUM(NSUInteger, MPEntryTab) {
@@ -58,6 +59,10 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
MPEntryTabAutotype
};
@interface NSObject (MPAppKitPrivateAPI)
- (void)_searchWithGoogleFromMenu:(id)obj;
@end
@interface MPEntryInspectorViewController () {
@private
NSArrayController *_attachmentsController;
@@ -75,6 +80,7 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
@property (nonatomic, assign) BOOL showPassword;
@property (nonatomic, assign) MPEntryTab activeTab;
@property (nonatomic, readonly) KPKEntry *representedEntry;
@property (strong) MPTOTPViewController *totpViewController;
@property (strong) MPTemporaryFileStorage *quicklookStorage;
@@ -117,6 +123,11 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
return nil;
}
- (void)setRepresentedObject:(id)representedObject {
super.representedObject = representedObject;
self.totpViewController.representedObject = self.representedObject;
}
- (void)viewDidLoad {
[self _addScrollViewWithView:self.generalView atTab:MPEntryTabGeneral];
@@ -125,7 +136,6 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
[self.infoTabControl bind:NSSelectedIndexBinding toObject:self withKeyPath:NSStringFromSelector(@selector(activeTab)) options:nil];
[self.tabView bind:NSSelectedIndexBinding toObject:self withKeyPath:NSStringFromSelector(@selector(activeTab)) options:nil];
self.attachmentTableView.backgroundColor = NSColor.clearColor;
[self.attachmentTableView bind:NSContentBinding toObject:_attachmentsController withKeyPath:NSStringFromSelector(@selector(arrangedObjects)) options:nil];
self.attachmentTableView.delegate = _attachmentTableDelegate;
@@ -141,12 +151,12 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
[self.generalView addSubview:customFieldTableView];
NSDictionary *dict = NSDictionaryOfVariableBindings(customFieldTableView, _tagsTokenField, _addCustomFieldButton);
NSDictionary *dict = NSDictionaryOfVariableBindings(customFieldTableView, _fieldsStackView, _addCustomFieldButton);
[self.generalView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-16-[customFieldTableView]-16-|"
options:0
metrics:nil
views:dict]];
[self.generalView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[_tagsTokenField]-[customFieldTableView]-[_addCustomFieldButton]"
[self.generalView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[_fieldsStackView]-[customFieldTableView]-[_addCustomFieldButton]"
options:0
metrics:nil
views:dict]];
@@ -154,6 +164,10 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
self.customFieldsTableView.backgroundColor = NSColor.clearColor;
self.customFieldsTableView.usesAutomaticRowHeights = YES;
if (@available(macOS 11.0, *)) {
self.customFieldsTableView.additionalSafeAreaInsets = NSEdgeInsetsZero;
}
[self.customFieldsTableView bind:NSContentBinding toObject:_customFieldsController withKeyPath:NSStringFromSelector(@selector(arrangedObjects)) options:nil];
self.customFieldsTableView.delegate = _customFieldTableDelegate;
@@ -171,8 +185,10 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
self.tagsTokenField.delegate = _tagTokenFieldDelegate;
[self _setupTOPTView];
[self _setupCustomFieldsButton];
[self _setupViewBindings];
[self _updateFieldVisibilty];
}
- (void)registerNotificationsForDocument:(MPDocument *)document {
@@ -187,10 +203,6 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
object:document];
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
#pragma mark -
#pragma mark Actions
@@ -219,7 +231,7 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
savePanel.nameFieldStringValue = binary.name;
[savePanel beginSheetModalForWindow:self.windowController.window completionHandler:^(NSInteger result) {
if(result == NSFileHandlingPanelOKButton) {
if(result == NSModalResponseOK) {
NSError *error;
BOOL sucess = [binary saveToLocation:savePanel.URL error:&error];
if(!sucess && error) {
@@ -237,7 +249,7 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
openPanel.prompt = NSLocalizedString(@"OPEN_BUTTON_ADD_ATTACHMENT_OPEN_PANEL", "Open button in the open panel to add attachments to an entry");
openPanel.message = NSLocalizedString(@"MESSAGE_ADD_ATTACHMENT_OPEN_PANEL", "Message in the open panel to add attachments to an entry");
[openPanel beginSheetModalForWindow:self.windowController.window completionHandler:^(NSInteger result) {
if(result == NSFileHandlingPanelOKButton) {
if(result == NSModalResponseOK) {
for (NSURL *attachmentURL in openPanel.URLs) {
KPKBinary *binary = [[KPKBinary alloc] initWithContentsOfURL:attachmentURL];
[self.observer willChangeModelProperty];
@@ -273,8 +285,8 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
KPKWindowAssociation *association = self.representedEntry.autotype.associations[row];
if(association) {
[self.representedEntry.autotype removeAssociation:association];
[self.observer didChangeModelProperty];
}
[self.observer didChangeModelProperty];
}
}
@@ -372,6 +384,22 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
[self _showPopopver:viewController atView:sender onEdge:NSMinYEdge];
}
- (IBAction)showOTPSetup:(id)sender {
NSView *location;
if([sender isKindOfClass:NSView.class]) {
location = sender;
}
if([sender isKindOfClass:NSMenuItem.class]) {
if([[sender representedObject] isKindOfClass:NSView.class]) {
location = [sender representedObject];
}
}
MPTOTPSetupViewController *vc = [[MPTOTPSetupViewController alloc] init];
vc.representedObject = self.representedObject;
[self _showPopopver:vc atView:location onEdge:NSMinYEdge];
}
- (void)dismissViewController:(NSViewController *)viewController {
if([viewController isKindOfClass:MPAutotypeBuilderViewController.class]) {
self.showCustomAssociationSequenceAutotypeBuilderButton.enabled = YES;
@@ -431,7 +459,7 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
metrics:nil
views:views]];
[[self view] layoutSubtreeIfNeeded];
[self.view layoutSubtreeIfNeeded];
}
#pragma mark -
@@ -464,6 +492,8 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
/* general */
NSDictionary *nullPlaceholderBindingOptionsDict = @{ NSNullPlaceholderBindingOption: NSLocalizedString(@"NONE", "Placeholder text for input fields if no entry or group is selected")};
NSDictionary *prettyPasswordBindingOptionsDict = @{ NSNullPlaceholderBindingOption: nullPlaceholderBindingOptionsDict[NSNullPlaceholderBindingOption], NSValueTransformerNameBindingOption : MPPrettyPasswordTransformerName };
[self.titleTextField bind:NSValueBinding
toObject:self
withKeyPath:[NSString stringWithFormat:@"%@.%@", NSStringFromSelector(@selector(representedObject)), NSStringFromSelector(@selector(title))]
@@ -471,19 +501,23 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
[self.passwordTextField bind:NSValueBinding
toObject:self
withKeyPath:[NSString stringWithFormat:@"%@.%@", NSStringFromSelector(@selector(representedObject)), NSStringFromSelector(@selector(password))]
options:nullPlaceholderBindingOptionsDict];
options:prettyPasswordBindingOptionsDict];
[self.usernameTextField bind:NSValueBinding
toObject:self
withKeyPath:[NSString stringWithFormat:@"%@.%@", NSStringFromSelector(@selector(representedObject)), NSStringFromSelector(@selector(username))]
options:nullPlaceholderBindingOptionsDict];
[self.URLTextField bind:NSValueBinding
toObject:self
withKeyPath:[NSString stringWithFormat:@"%@.%@", NSStringFromSelector(@selector(representedObject)), NSStringFromSelector(@selector(url))]
options:nullPlaceholderBindingOptionsDict];
[self.expiresCheckButton bind:NSTitleBinding
toObject:self
withKeyPath:[NSString stringWithFormat:@"%@.%@.%@", NSStringFromSelector(@selector(representedObject)), NSStringFromSelector(@selector(timeInfo)), NSStringFromSelector(@selector(expirationDate))]
options:@{ NSValueTransformerNameBindingOption:MPExpiryDateValueTransformerName }];
[self.expiresCheckButton bind:NSValueBinding
toObject:self
withKeyPath:[NSString stringWithFormat:@"%@.%@.%@", NSStringFromSelector(@selector(representedObject)), NSStringFromSelector(@selector(timeInfo)), NSStringFromSelector(@selector(expires))]
@@ -557,7 +591,20 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
NSMenu *customFieldMenu = [[NSMenu alloc] initWithTitle:NSLocalizedString(@"ADD_CUSTOM_FIELD_CONTEXT_MENU", @"Menu displayed for adding special custom keys")];
customFieldMenu.delegate = _addCustomFieldContextMenuDelegate;
self.addCustomFieldButton.contextMenu = customFieldMenu;
[self.addCustomFieldButton setEnabled:NO forSegment:MPContextButtonSegmentContextButton];
//[self.addCustomFieldButton setEnabled:NO forSegment:MPContextButtonSegmentContextButton];
}
- (void)_updateFieldVisibilty {
}
- (void)_setupTOPTView {
self.totpViewController = [[MPTOTPViewController alloc] init];
NSInteger urlindex = [self.fieldsStackView.arrangedSubviews indexOfObject:self.URLTextField];
NSAssert(urlindex != NSNotFound, @"Missing reference view. This should not happen!");
[self addChildViewController:self.totpViewController];
[self.fieldsStackView insertArrangedSubview:self.totpViewController.view atIndex:urlindex - 1];
}
#pragma mark -
@@ -624,14 +671,14 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
name = [_customFieldsController.arrangedObjects[index] key];
}
}
[MPPasteBoardController.defaultController copyObjects:@[selectedValue] overlayInfo:info name:name atView:self.view];
[MPPasteBoardController.defaultController copyObject:selectedValue overlayInfo:info name:name atView:self.view];
return NO;
}
return YES;
}
- (IBAction)toggleExpire:(NSButton*)sender {
if([sender state] == NSOnState && [self.representedEntry.timeInfo.expirationDate isEqualToDate:[NSDate distantFuture]]) {
if([sender state] == NSOnState && [self.representedEntry.timeInfo.expirationDate isEqualToDate:NSDate.distantFuture]) {
[NSApp sendAction:self.pickExpireDateButton.action to:nil from:self.pickExpireDateButton];
}
}
@@ -646,7 +693,12 @@ typedef NS_ENUM(NSUInteger, MPEntryTab) {
- (void)_didChangeCurrentItem:(NSNotification *)notificiation {
self.showPassword = NO;
//self.customFieldsTableView.needsDisplay = YES;
}
#pragma mark -
#pragma mark KPKEntry Notifications
- (void)_didChangeAttribute:(NSNotification *)notification {
}
@end

View File

@@ -24,17 +24,6 @@
#import "MPContextBarViewController.h"
#import "MPTargetNodeResolving.h"
APPKIT_EXTERN NSString *const MPEntryTableIndexColumnIdentifier;
APPKIT_EXTERN NSString *const MPEntryTableUserNameColumnIdentifier;
APPKIT_EXTERN NSString *const MPEntryTableTitleColumnIdentifier;
APPKIT_EXTERN NSString *const MPEntryTablePasswordColumnIdentifier;
APPKIT_EXTERN NSString *const MPEntryTableParentColumnIdentifier;
APPKIT_EXTERN NSString *const MPEntryTableURLColumnIdentifier;
APPKIT_EXTERN NSString *const MPEntryTableNotesColumnIdentifier;
APPKIT_EXTERN NSString *const MPEntryTableAttachmentColumnIdentifier;
APPKIT_EXTERN NSString *const MPEntryTableModfiedColumnIdentifier;
APPKIT_EXTERN NSString *const MPEntryTableHistoryColumnIdentifier;
typedef NS_ENUM(NSUInteger, MPDisplayMode) {
MPDisplayModeEntries,
MPDisplayModeSearchResults,

View File

@@ -62,6 +62,7 @@ NSString *const MPEntryTableParentColumnIdentifier = @"MPParentColumnIdentifier"
NSString *const MPEntryTableURLColumnIdentifier = @"MPEntryTableURLColumnIdentifier";
NSString *const MPEntryTableNotesColumnIdentifier = @"MPEntryTableNotesColumnIdentifier";
NSString *const MPEntryTableAttachmentColumnIdentifier = @"MPEntryTableAttachmentColumnIdentifier";
NSString *const MPEntryTableCreatedColumnIdentifier = @"MPEntryTableCreatedColumnIdentifier";
NSString *const MPEntryTableModfiedColumnIdentifier = @"MPEntryTableModfiedColumnIdentifier";
NSString *const MPEntryTableHistoryColumnIdentifier = @"MPEntryTableHistoryColumnIdentifier";
@@ -146,11 +147,13 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
NSTableColumn *urlColumn = self.entryTable.tableColumns[4];
NSTableColumn *attachmentsColumn = [[NSTableColumn alloc] initWithIdentifier:MPEntryTableAttachmentColumnIdentifier];
NSTableColumn *notesColumn = [[NSTableColumn alloc] initWithIdentifier:MPEntryTableNotesColumnIdentifier];
NSTableColumn *createdColumn = [[NSTableColumn alloc] initWithIdentifier:MPEntryTableCreatedColumnIdentifier];
NSTableColumn *modifiedColumn = [[NSTableColumn alloc] initWithIdentifier:MPEntryTableModfiedColumnIdentifier];
NSTableColumn *historyColumn = [[NSTableColumn alloc] initWithIdentifier:MPEntryTableHistoryColumnIdentifier];
NSTableColumn *indexColumn = [[NSTableColumn alloc] initWithIdentifier:MPEntryTableIndexColumnIdentifier];
notesColumn.minWidth = 40.0;
attachmentsColumn.minWidth = 40.0;
createdColumn.minWidth = 40.0;
modifiedColumn.minWidth = 40.0;
historyColumn.minWidth = 40.0;
indexColumn.minWidth = 27.0;
@@ -158,6 +161,7 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
[self.entryTable addTableColumn:notesColumn];
[self.entryTable addTableColumn:attachmentsColumn];
[self.entryTable addTableColumn:modifiedColumn];
[self.entryTable addTableColumn:createdColumn];
[self.entryTable addTableColumn:historyColumn];
[self.entryTable addTableColumn:indexColumn];
@@ -172,6 +176,7 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
NSString *parentTitleKeyPath = [[NSString alloc] initWithFormat:@"%@.%@", NSStringFromSelector(@selector(parent)), NSStringFromSelector(@selector(title))];
NSString *timeInfoModificationTimeKeyPath = [[NSString alloc] initWithFormat:@"%@.%@", NSStringFromSelector(@selector(timeInfo)), NSStringFromSelector(@selector(modificationDate))];
NSString *timeInfoCreationTimeKeyPath = [[NSString alloc] initWithFormat:@"%@.%@", NSStringFromSelector(@selector(timeInfo)), NSStringFromSelector(@selector(creationDate))];
indexColumn.sortDescriptorPrototype = [NSSortDescriptor sortDescriptorWithKey:NSStringFromSelector(@selector(index)) ascending:YES selector:@selector(compare:)];
titleColumn.sortDescriptorPrototype = [NSSortDescriptor sortDescriptorWithKey:NSStringFromSelector(@selector(title))ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)];
@@ -179,6 +184,7 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
urlColumn.sortDescriptorPrototype = [NSSortDescriptor sortDescriptorWithKey:NSStringFromSelector(@selector(url)) ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)];
parentColumn.sortDescriptorPrototype = [NSSortDescriptor sortDescriptorWithKey:parentTitleKeyPath ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)];
modifiedColumn.sortDescriptorPrototype = [NSSortDescriptor sortDescriptorWithKey:timeInfoModificationTimeKeyPath ascending:YES selector:@selector(compare:)];
createdColumn.sortDescriptorPrototype = [NSSortDescriptor sortDescriptorWithKey:timeInfoCreationTimeKeyPath ascending:YES selector:@selector(compare:)];
indexColumn.headerCell.stringValue = @"";
indexColumn.headerToolTip = NSLocalizedString(@"ENTRY_INDEX_COLUMN_TOOLTIP", "Tooltip displayed on the index header cell");
@@ -189,6 +195,7 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
urlColumn.headerCell.stringValue = NSLocalizedString(@"URL", "Url column title");
notesColumn.headerCell.stringValue = NSLocalizedString(@"NOTES", "Notes column title");
attachmentsColumn.headerCell.stringValue = NSLocalizedString(@"ATTACHMENTS", "Attachments column title (shows counts)");
createdColumn.headerCell.stringValue = NSLocalizedString(@"CREATED", "Creating date column title");
modifiedColumn.headerCell.stringValue = NSLocalizedString(@"MODIFIED", "Modification date column title");
historyColumn.headerCell.stringValue = NSLocalizedString(@"HISTORY", "History count column title");
@@ -253,7 +260,6 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
entry.parent.lastTopVisibleEntry = entry.uuid;
}
}
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
BOOL isTitleColumn = [tableColumn.identifier isEqualToString:MPEntryTableTitleColumnIdentifier];
BOOL isGroupColumn = [tableColumn.identifier isEqualToString:MPEntryTableParentColumnIdentifier];
@@ -262,6 +268,7 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
BOOL isURLColumn = [tableColumn.identifier isEqualToString:MPEntryTableURLColumnIdentifier];
BOOL isAttachmentColumn = [tableColumn.identifier isEqualToString:MPEntryTableAttachmentColumnIdentifier];
BOOL isNotesColumn = [tableColumn.identifier isEqualToString:MPEntryTableNotesColumnIdentifier];
BOOL isCreatedColumn = [tableColumn.identifier isEqualToString:MPEntryTableCreatedColumnIdentifier];
BOOL isModifedColumn = [tableColumn.identifier isEqualToString:MPEntryTableModfiedColumnIdentifier];
BOOL isHistoryColumn = [tableColumn.identifier isEqualToString:MPEntryTableHistoryColumnIdentifier];
@@ -308,12 +315,12 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
view = [tableView makeViewWithIdentifier:_MPTableStringCellView owner:self];
[view.textField unbind:NSValueBinding];
view.textField.stringValue = @"";
if(!isModifedColumn) {
if(!isModifedColumn && !isCreatedColumn) {
/* clean up old formatter that might be left */
view.textField.formatter = nil;
}
if(isModifedColumn) {
if(isModifedColumn || isCreatedColumn) {
if(!view.textField.formatter) {
/* Just use one formatter instance since it's expensive to create */
static NSDateFormatter *formatter = nil;
@@ -325,12 +332,23 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
});
view.textField.formatter = formatter;
}
NSString *modificationTimeKeyPath = [NSString stringWithFormat:@"%@.%@.%@",
NSStringFromSelector(@selector(objectValue)),
NSStringFromSelector(@selector(timeInfo)),
NSStringFromSelector(@selector(modificationDate))];
if(isModifedColumn) {
NSString *modificationTimeKeyPath = [NSString stringWithFormat:@"%@.%@.%@",
NSStringFromSelector(@selector(objectValue)),
NSStringFromSelector(@selector(timeInfo)),
NSStringFromSelector(@selector(modificationDate))];
[view.textField bind:NSValueBinding toObject:view withKeyPath:modificationTimeKeyPath options:nil];
[view.textField bind:NSValueBinding toObject:view withKeyPath:modificationTimeKeyPath options:nil];
}
else {
NSString * createdTimeKeyPath = [NSString stringWithFormat:@"%@.%@.%@",
NSStringFromSelector(@selector(objectValue)),
NSStringFromSelector(@selector(timeInfo)),
NSStringFromSelector(@selector(creationDate))];
[view.textField bind:NSValueBinding toObject:view withKeyPath:createdTimeKeyPath options:nil];
}
return view;
}
else if(isURLColumn) {
@@ -382,8 +400,11 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
if(tableView != self.entryTable) {
return; // Not the right table view
}
MPDocument *document = self.windowController.document;
document.selectedEntries = self.entryArrayController.selectedObjects;
/* do not update the current item if we are not in focus! */
if(tableView.window.firstResponder == self.entryTable) {
MPDocument *document = self.windowController.document;
document.selectedEntries = self.entryArrayController.selectedObjects;
}
}
- (BOOL)tableView:(NSTableView *)tableView shouldReorderColumn:(NSInteger)columnIndex toColumn:(NSInteger)newColumnIndex {
@@ -472,6 +493,10 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
NSUInteger row = [self.entryArrayController.arrangedObjects indexOfObject:entry];
[self.entryTable scrollRowToVisible:row];
[self.entryTable selectRowIndexes:[NSIndexSet indexSetWithIndex:row] byExtendingSelection:NO];
// since we do not update the current selection when the table view is not first responder, do it here manually
if(self.entryTable.window.firstResponder != self.entryTable) {
document.selectedEntries = self.entryArrayController.selectedObjects;
}
}
- (void)_didUpdateSearchResults:(NSNotification *)notification {
@@ -620,8 +645,10 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
[headerMenu addItemWithTitle:NSLocalizedString(@"NOTES", "Menu item to toggle display of notes column in entry table") action:NULL keyEquivalent:@""];
[headerMenu addItemWithTitle:NSLocalizedString(@"ATTACHMENTS", "Menu item to toggle display of attachment count column in entry table") action:NULL keyEquivalent:@""];
[headerMenu addItemWithTitle:NSLocalizedString(@"MODIFIED", "Menu item to toggle display of modified date column in entry table") action:NULL keyEquivalent:@""];
[headerMenu addItemWithTitle:NSLocalizedString(@"CREATED", "Menu item to toggle display of created date column in entry table") action:NULL keyEquivalent:@""];
[headerMenu addItemWithTitle:NSLocalizedString(@"HISTORY", "Menu item to toggle display of history count column in entry table") action:NULL keyEquivalent:@""];
NSArray *identifier = @[ MPEntryTableTitleColumnIdentifier,
MPEntryTableUserNameColumnIdentifier,
MPEntryTablePasswordColumnIdentifier,
@@ -629,6 +656,7 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
MPEntryTableNotesColumnIdentifier,
MPEntryTableAttachmentColumnIdentifier,
MPEntryTableModfiedColumnIdentifier,
MPEntryTableCreatedColumnIdentifier,
MPEntryTableHistoryColumnIdentifier ];
NSDictionary *options = @{ NSValueTransformerNameBindingOption : NSNegateBooleanTransformerName };
@@ -647,7 +675,7 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
KPKEntry *selectedEntry = nodes.count == 1 ? [nodes.firstObject asEntry] : nil;
NSString *value = [selectedEntry.password kpk_finalValueForEntry:selectedEntry];
if(value) {
[MPPasteBoardController.defaultController copyObjects:@[value] overlayInfo:MPPasteboardOverlayInfoPassword name:nil atView:self.view];
[MPPasteBoardController.defaultController copyObject:value overlayInfo:MPPasteboardOverlayInfoPassword name:nil atView:self.view];
}
}
@@ -656,7 +684,7 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
KPKEntry *selectedEntry = nodes.count == 1 ? [nodes.firstObject asEntry] : nil;
NSString *value = [selectedEntry.username kpk_finalValueForEntry:selectedEntry];
if(value) {
[MPPasteBoardController.defaultController copyObjects:@[value] overlayInfo:MPPasteboardOverlayInfoUsername name:nil atView:self.view];
[MPPasteBoardController.defaultController copyObject:value overlayInfo:MPPasteboardOverlayInfoUsername name:nil atView:self.view];
}
}
@@ -669,7 +697,7 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
KPKAttribute *attribute = selectedEntry.customAttributes[index];
NSString *value = attribute.evaluatedValue;
if(value) {
[MPPasteBoardController.defaultController copyObjects:@[value] overlayInfo:MPPasteboardOverlayInfoCustom name:attribute.key atView:self.view];
[MPPasteBoardController.defaultController copyObject:value overlayInfo:MPPasteboardOverlayInfoCustom name:attribute.key atView:self.view];
}
}
}
@@ -679,7 +707,7 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
KPKEntry *selectedEntry = nodes.count == 1 ? [nodes.firstObject asEntry] : nil;
NSString *value = [selectedEntry.url kpk_finalValueForEntry:selectedEntry];
if(value) {
[MPPasteBoardController.defaultController copyObjects:@[value] overlayInfo:MPPasteboardOverlayInfoURL name:nil atView:self.view];
[MPPasteBoardController.defaultController copyObject:value overlayInfo:MPPasteboardOverlayInfoURL name:nil atView:self.view];
}
}
@@ -718,7 +746,7 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
kKPKReferenceTitleKey: NSLocalizedString(@"COPIED_TITLE_REFERENCE", "Context menu that copies reference to title"),
kKPKReferencePasswordKey: NSLocalizedString(@"COPIED_PASSWORD_REFERENCE", "Context menu that copies reference to password"),
kKPKReferenceUsernameKey: NSLocalizedString(@"COPIED_USERNAME_REFERENCE", "Context menu that copies reference to username"),
};
};
if(![sender isKindOfClass:NSMenuItem.class]) {
return;
}
@@ -727,7 +755,7 @@ NSString *const _MPTableSecurCellView = @"PasswordCell";
KPKEntry *selectedEntry = nodes.count == 1 ? [nodes.firstObject asEntry] : nil;
if(referencesField && selectedEntry) {
NSString *value = [NSString stringWithFormat:@"{%@%@@%@:%@}", kKPKReferencePrefix, referencesField, kKPKReferenceUUIDKey, selectedEntry.uuid.UUIDString];
[MPPasteBoardController.defaultController copyObjects:@[value] overlayInfo:MPPasteboardOverlayInfoReference name:references[referencesField] atView:self.view];
[MPPasteBoardController.defaultController copyObject:value overlayInfo:MPPasteboardOverlayInfoReference name:references[referencesField] atView:self.view];
}
}

View File

@@ -37,5 +37,6 @@
@property (strong) IBOutlet NSButton *enableAutosaveCheckButton;
@property (strong) IBOutlet NSButton *rememberKeyFileCheckButton;
@property (strong) IBOutlet NSPopUpButton *fileChangeStrategyPopup;
@property (strong) IBOutlet NSPopUpButton *faviconDownloadMethodPopup;
@end

View File

@@ -56,6 +56,19 @@
[self.enableAutosaveCheckButton bind:NSValueBinding toObject:defaultsController withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingsKeyEnableAutosave] options:nil];
[self.rememberKeyFileCheckButton bind:NSValueBinding toObject:defaultsController withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingsKeyRememberKeyFilesForDatabases] options:nil];
/* Favicon download method menu */
NSDictionary *faviconDownloadMethodDict = @{ @(MPFaviconDownloadMethodDirect) : NSLocalizedString(@"FAVICON_DOWNLOAD_METHOD_DIRECT", @"Favicon download method: directly download from the host"),
@(MPFaviconDownloadMethodDuckDuckGo) : NSLocalizedString(@"FAVICON_DOWNLOAD_METHOD_DUCKDUCKGO", @"Favicon download method: use DuckDuckGo's favicon fetching service"),
@(MPFaviconDownloadMethodGoogle) : NSLocalizedString(@"FAVICON_DOWNLOAD_METHOD_GOOGLE", @"Favicon download method: use Google's favicon fetching service"),
};
[self.faviconDownloadMethodPopup.menu removeAllItems];
for(NSNumber *key in faviconDownloadMethodDict) {
NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:faviconDownloadMethodDict[key] action:NULL keyEquivalent:@""];
item.tag = key.integerValue;
[self.faviconDownloadMethodPopup.menu addItem:item];
}
[self.faviconDownloadMethodPopup bind:NSSelectedTagBinding toObject:defaultsController withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingsKeyFaviconDownloadMethod] options:nil];
/* File Change Strategy Menu */
NSDictionary *fileChangeStragegyDict = @{ @(MPFileChangeStrategyAsk) : NSLocalizedString(@"FILE_CHANGE_STRATEGY_ASK", @"External file change strategy option: ask what to do"),
@(MPFileChangeStrategyUseOther) : NSLocalizedString(@"FILE_CHANGE_STRATEGY_USE_OTHER", @"External file change strategy option: Use the changed file and discard local changes"),

View File

@@ -101,7 +101,7 @@ typedef NS_ENUM(NSUInteger, MPIconType) {
MPIconPhone,
/* Custom Icons not used in Database */
MPCustomIconTypeBegin = 1000,
MPIconInfo,
MPIconSidebar,
MPIconAddFolder,
MPIconHardDisk,
MPIconCreated,
@@ -130,19 +130,21 @@ typedef NS_ENUM(NSUInteger, MPIconType) {
* Available Icon names (all)
* @return Dictionary with MPIconType keys and NSString values containing their names
*/
+ (NSDictionary *)availableIconNames;
@property (class, nonatomic, strong, readonly) NSDictionary *availableIconNames;
@property (class, nonatomic, strong, readonly) NSDictionary *availableSymbolNames;
/**
* List of all available DatabaseIcons as an array of Images. Sorted by IconIndex.
* @return Array of Icons as NSImage objects
*/
+ (NSArray<KPKIcon *> *)databaseIcons;
@property (class, nonatomic, strong, readonly) NSArray<KPKIcon *> *databaseIcons;
/**
* List of all available DatabaseIcons as an array of MPIconType. Sorted by IconIndex.
* @return Array of MPIconType as NSNumber objects
*/
+ (NSArray *)databaseIconTypes;
@property (class, nonatomic, strong, readonly) NSArray *databaseIconTypes;
+ (void)fetchIconDataForURL:(NSURL *)url completionHandler:(void (^)(NSData *iconData))handler;

View File

@@ -21,19 +21,39 @@
//
#import "MPIconHelper.h"
#import "MPSettingsHelper.h"
#import "KeePassKit/KeePassKit.h"
@implementation MPIconHelper
+ (NSImage *)icon:(MPIconType)type {
static NSDictionary *icons;
if(!icons) {
icons = [MPIconHelper availableIconNames];
if (@available(macOS 11.0, *)) {
static NSDictionary *symbols;
if(!symbols) {
symbols = MPIconHelper.availableSymbolNames;
}
if([symbols.allKeys containsObject:@(type)]) {
NSString *imageName = symbols[@(type)];
NSImage *image = [NSImage imageWithSystemSymbolName:imageName accessibilityDescription:nil];
if(image) {
return image;
}
}
}
if([[icons allKeys] containsObject:@(type)]) {
static NSDictionary *icons;
if(!icons) {
icons = MPIconHelper.availableIconNames;
}
if([icons.allKeys containsObject:@(type)]) {
NSString *imageName = icons[@(type)];
NSImage *image = [NSImage imageNamed:imageName];
return image;
if(image) {
return image;
}
}
return [NSImage imageNamed:NSImageNameActionTemplate];
}
@@ -42,7 +62,7 @@
static NSArray *icons;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSDictionary *imageNames = [MPIconHelper availableIconNames];
NSDictionary *imageNames = MPIconHelper.availableIconNames;
NSMutableArray *mutableIcons = [[NSMutableArray alloc] initWithCapacity:imageNames.count];
NSArray *sortedImageNames = [imageNames.allKeys sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
@@ -67,10 +87,10 @@
static NSArray *iconTypes;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSDictionary *imageNames = [MPIconHelper availableIconNames];
NSDictionary *imageNames = MPIconHelper.availableIconNames;
NSArray *sortedImageNames = [[imageNames allKeys] sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
return [[imageNames objectForKey:obj1] compare:[imageNames objectForKey:obj2]];
NSArray *sortedImageNames = [imageNames.allKeys sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
return [imageNames[obj1] compare:imageNames[obj2]];
}];
iconTypes = [sortedImageNames filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
NSNumber *iconNumber = (NSNumber *)evaluatedObject;
@@ -80,93 +100,189 @@
return iconTypes;
}
+ (NSDictionary *)availableSymbolNames {
static NSDictionary *symbolNames;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
symbolNames = @{
@(MPIconPassword) : @"ellipsis.rectangle",
@(MPIconPackageNetwork) : @"globe",
@(MPIconWarning) : @"exclamationmark.triangle",
@(MPIconServer) : @"server.rack",
@(MPIconKlipper) : @"pin",
@(MPIconLanguages) : @"mouth",
@(MPIconBlockDevice) : @"gearshape.2",
@(MPIconNotepad) : @"note.text",
@(MPIconSocket) : @"rectangle.connected.to.line.below",
@(MPIconIdentity) : @"person.crop.square.fill.and.at.rectangle",
@(MPIconContact) : @"at",
@(MPIconCamera) : @"camera",
@(MPIconRemote) : @"icloud.fill",
@(MPIconKeys) : @"key",
@(MPIconBattery) : @"bolt.fill.batteryblock",
@(MPIconScanner) : @"scanner",
@(MPIconBrowser) : @"safari",
@(MPIconCDRom) : @"opticaldisc",
@(MPIconDisplay) : @"display",
@(MPIconEmail) : @"envelope",
@(MPIconMisc) : @"ellipsis.circle",
@(MPIconOrganizer) : @"list.number",
@(MPIconASCII) : @"doc.text",
@(MPIconIcons) : @"square.grid.3x3.fill.square",
@(MPIconEstablishedConnection) : @"bolt",
@(MPIconMailFolder) : @"tray.full",
@(MPIconFileSave) : @"square.and.arrow.down",
@(MPIconNFSUnmount) : @"externaldrive.connected.to.line.below",
@(MPIconQuickTime) : @"film",
@(MPIconSecureTerminal) : @"terminal",
@(MPIconTerminal) : @"terminal",
@(MPIconPrint) : @"printer",
@(MPIconFileSystemView) : @"square.grid.2x2",
@(MPIconRun) : @"figure.walk.diamond",
@(MPIconConfigure) : @"slider.vertical.3",
@(MPIconBrowserWindow) : @"macwindow",
@(MPIconArchive) : @"doc.zipper",
@(MPIconPercentage) : @"percent",
@(MPIconSambaUnmount) : @"externaldrive.badge.xmark",
@(MPIconHistory) : @"clock.arrow.circlepath",
@(MPIconFindMail) : @"mail.and.text.magnifyingglass",
@(MPIconVector) : @"skew",
@(MPIconMemory) : @"memorychip",
@(MPIconTrash) : @"trash",
@(MPIconNotes) : @"note.text",
@(MPIconCancel) : @"xmark.circle",
@(MPIconHelp) : @"questionmark.circle.fill",
@(MPIconPackage) : @"shippingbox",
@(MPIconFolder) : @"folder",
@(MPIconFolderOpen) : @"folder",
@(MPIconFolderTar) : @"archivebox",
@(MPIconDecrypted) : @"lock.open",
@(MPIconEncrypted) : @"lock",
@(MPIconApply) : @"checkmark.square",
@(MPIconSignature) : @"signature",
@(MPIconThumbnail) : @"photo",
@(MPIconAddressBook) : @"rectangle.stack.person.crop",
@(MPIconTextView) : @"text.justifyleft",
@(MPIconSecureAccount) : @"person.fill.viewfinder",
@(MPIconDevelopment) : @"hammer",
@(MPIconHome) : @"house",
@(MPIconServices) : @"star",
@(MPIconTux) : @"ladybug",
@(MPIconFeather) : @"lightbulb",
@(MPIconApple) : @"applelogo",
@(MPIconWiki) : @"w.circle",
@(MPIconMoney) : @"dollarsign.circle",
@(MPIconCertificat) : @"signature", // FIXME: find better icon
@(MPIconPhone) : @"iphone",
/* Custom */
@(MPIconSidebar) : @"sidebar.trailing",
@(MPIconAddFolder) : @"folder.badge.plus",
@(MPIconHardDisk) : @"internaldrive",
@(MPIconCreated) : @"staroflife", // FIXME: find better icon
@(MPIconAddEntry) : @"ellipsis.rectangle", // FIXME: find better icon
@(MPIconContextTriangle) : @"arrowtriangle.down.fill",
@(MPIconKeyboard) : @"keyboard",
@(MPIconExpiredEntry) : @"exclamationmark.octagon.fill",
@(MPIconExpiredGroup) : @"exclamationmark.octagon.fill"
};
});
if(@available(macOS 11.0, *)) {
return symbolNames;
}
else {
return nil;
}
}
+ (NSDictionary *)availableIconNames {
static NSDictionary *imageNames;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
imageNames = @{
@(MPIconPassword): @"00_PasswordTemplate",
@(MPIconPackageNetwork): @"01_PackageNetworkTemplate",
@(MPIconWarning): @"02_MessageBoxWarningTemplate",
@(MPIconServer): @"03_ServerTemplate",
@(MPIconKlipper): @"04_KlipperTemplate",
@(MPIconLanguages): @"05_LanguagesTemplate",
@(MPIconBlockDevice): @"06_BlockDeviceTemplate",
@(MPIconNotepad): @"07_NotepadTemplate",
@(MPIconSocket): @"08_SocketTemplate",
@(MPIconIdentity): @"09_IdentityTemplate",
@(MPIconContact): @"10_ContactTemplate",
@(MPIconCamera): @"11_CameraTemplate",
@(MPIconRemote): @"12_RemoteTemplate",
@(MPIconKeys): @"13_KeysTemplate",
@(MPIconBattery): @"14_BatteryTemplate",
@(MPIconScanner): @"15_ScannerTemplate",
@(MPIconBrowser): @"16_BrowserTemplate",
@(MPIconCDRom): @"17_CDRomTemplate",
@(MPIconDisplay): @"18_DisplayTemplate",
@(MPIconEmail): @"19_EmailTemplate",
@(MPIconMisc): @"20_MiscTemplate",
@(MPIconOrganizer): @"21_OrganizerTemplate",
@(MPIconASCII): @"22_ASCIITemplate",
@(MPIconIcons): @"23_IconsTemplate",
@(MPIconEstablishedConnection): @"24_EstablishedConnectionTemplate",
@(MPIconMailFolder): @"25_MailFolderTemplate",
@(MPIconFileSave): @"26_FileSaveTemplate",
@(MPIconNFSUnmount) :@"27_NFSUnmountTemplate",
@(MPIconQuickTime) : @"28_QuickTimeTemplate",
@(MPIconSecureTerminal) : @"29_SecureTerminalTemplate",
@(MPIconTerminal) : @"30_TerminalTemplate",
@(MPIconPrint) : @"31_PrintTemplate",
@(MPIconFileSystemView) : @"32_FileSystemViewTemplate",
@(MPIconRun) : @"33_RunTemplate",
@(MPIconConfigure) : @"34_ConfigureTemplate",
@(MPIconBrowserWindow) : @"35_BrowserWindowTemplate",
@(MPIconArchive) : @"36_ArchiveTemplate",
@(MPIconPercentage) : @"37_PercentageTemplate",
@(MPIconSambaUnmount) : @"38_SambaUnmountTemplate",
@(MPIconHistory) : @"39_HistoryTemplate",
@(MPIconFindMail) : @"40_FindMailTemplate",
@(MPIconVector) : @"41_VectorTemplate",
@(MPIconMemory) : @"42_MemoryTemplate",
@(MPIconTrash): @"43_TrashTemplate",
@(MPIconNotes) : @"44_NotesTemplate",
@(MPIconCancel) : @"45_CancelTemplate",
@(MPIconHelp) : @"46_HelpTemplate",
@(MPIconPackage) : @"47_PackageTemplate",
@(MPIconFolder): @"48_FolderTemplate",
@(MPIconFolderOpen) : @"49_FolderOpenTemplate",
@(MPIconFolderTar) : @"50_FolderTarTemplate",
@(MPIconDecrypted) : @"51_DecryptedTemplate",
@(MPIconEncrypted) : @"52_EncryptedTemplate",
@(MPIconApply) : @"53_ApplyTemplate",
@(MPIconSignature) : @"54_SignatureTemplate",
@(MPIconThumbnail) : @"55_ThumbnailTemplate",
@(MPIconAddressBook) : @"56_AddressBookTemplate",
@(MPIconTextView) : @"57_TextViewTemplate",
@(MPIconSecureAccount) : @"58_SecureAccountTemplate",
@(MPIconDevelopment) : @"59_DevelopmentTemplate",
@(MPIconHome) : @"60_HomeTemplate",
@(MPIconServices) : @"61_ServicesTemplate",
@(MPIconTux) : @"62_TuxTemplate",
@(MPIconFeather) : @"63_FeatherTemplate",
@(MPIconApple) : @"64_AppleTemplate",
@(MPIconWiki) : @"65_WikiTemplate",
@(MPIconMoney) : @"66_MoneyTemplate",
@(MPIconCertificat) : @"67_CertificatTemplate",
@(MPIconPhone): @"68_PhoneTemplate",
/* Custom */
@(MPIconInfo): @"infoTemplate",
@(MPIconAddFolder): @"addFolderTemplate",
@(MPIconHardDisk): @"harddiskTemplate",
@(MPIconCreated): @"createdTemplate",
@(MPIconAddEntry): @"addEntryTemplate",
@(MPIconContextTriangle): @"contextTriangleTemplate",
@(MPIconKeyboard): @"keyboardTemplate",
@(MPIconPassword) : @"00_PasswordTemplate",
@(MPIconPackageNetwork) : @"01_PackageNetworkTemplate",
@(MPIconWarning) : @"02_MessageBoxWarningTemplate",
@(MPIconServer) : @"03_ServerTemplate",
@(MPIconKlipper) : @"04_KlipperTemplate",
@(MPIconLanguages) : @"05_LanguagesTemplate",
@(MPIconBlockDevice) : @"06_BlockDeviceTemplate",
@(MPIconNotepad) : @"07_NotepadTemplate",
@(MPIconSocket) : @"08_SocketTemplate",
@(MPIconIdentity) : @"09_IdentityTemplate",
@(MPIconContact) : @"10_ContactTemplate",
@(MPIconCamera) : @"11_CameraTemplate",
@(MPIconRemote) : @"12_RemoteTemplate",
@(MPIconKeys) : @"13_KeysTemplate",
@(MPIconBattery) : @"14_BatteryTemplate",
@(MPIconScanner) : @"15_ScannerTemplate",
@(MPIconBrowser) : @"16_BrowserTemplate",
@(MPIconCDRom) : @"17_CDRomTemplate",
@(MPIconDisplay) : @"18_DisplayTemplate",
@(MPIconEmail) : @"19_EmailTemplate",
@(MPIconMisc) : @"20_MiscTemplate",
@(MPIconOrganizer) : @"21_OrganizerTemplate",
@(MPIconASCII) : @"22_ASCIITemplate",
@(MPIconIcons) : @"23_IconsTemplate",
@(MPIconEstablishedConnection) : @"24_EstablishedConnectionTemplate",
@(MPIconMailFolder) : @"25_MailFolderTemplate",
@(MPIconFileSave) : @"26_FileSaveTemplate",
@(MPIconNFSUnmount) : @"27_NFSUnmountTemplate",
@(MPIconQuickTime) : @"28_QuickTimeTemplate",
@(MPIconSecureTerminal) : @"29_SecureTerminalTemplate",
@(MPIconTerminal) : @"30_TerminalTemplate",
@(MPIconPrint) : @"31_PrintTemplate",
@(MPIconFileSystemView) : @"32_FileSystemViewTemplate",
@(MPIconRun) : @"33_RunTemplate",
@(MPIconConfigure) : @"34_ConfigureTemplate",
@(MPIconBrowserWindow) : @"35_BrowserWindowTemplate",
@(MPIconArchive) : @"36_ArchiveTemplate",
@(MPIconPercentage) : @"37_PercentageTemplate",
@(MPIconSambaUnmount) : @"38_SambaUnmountTemplate",
@(MPIconHistory) : @"39_HistoryTemplate",
@(MPIconFindMail) : @"40_FindMailTemplate",
@(MPIconVector) : @"41_VectorTemplate",
@(MPIconMemory) : @"42_MemoryTemplate",
@(MPIconTrash) : @"43_TrashTemplate",
@(MPIconNotes) : @"44_NotesTemplate",
@(MPIconCancel) : @"45_CancelTemplate",
@(MPIconHelp) : @"46_HelpTemplate",
@(MPIconPackage) : @"47_PackageTemplate",
@(MPIconFolder) : @"48_FolderTemplate",
@(MPIconFolderOpen) : @"49_FolderOpenTemplate",
@(MPIconFolderTar) : @"50_FolderTarTemplate",
@(MPIconDecrypted) : @"51_DecryptedTemplate",
@(MPIconEncrypted) : @"52_EncryptedTemplate",
@(MPIconApply) : @"53_ApplyTemplate",
@(MPIconSignature) : @"54_SignatureTemplate",
@(MPIconThumbnail) : @"55_ThumbnailTemplate",
@(MPIconAddressBook) : @"56_AddressBookTemplate",
@(MPIconTextView) : @"57_TextViewTemplate",
@(MPIconSecureAccount) : @"58_SecureAccountTemplate",
@(MPIconDevelopment) : @"59_DevelopmentTemplate",
@(MPIconHome) : @"60_HomeTemplate",
@(MPIconServices) : @"61_ServicesTemplate",
@(MPIconTux) : @"62_TuxTemplate",
@(MPIconFeather) : @"63_FeatherTemplate",
@(MPIconApple) : @"64_AppleTemplate",
@(MPIconWiki) : @"65_WikiTemplate",
@(MPIconMoney) : @"66_MoneyTemplate",
@(MPIconCertificat) : @"67_CertificatTemplate",
@(MPIconPhone) : @"68_PhoneTemplate",
/* Custom */
@(MPIconSidebar) : NSImageNameTouchBarGetInfoTemplate,
@(MPIconAddFolder) : @"addFolderTemplate",
@(MPIconHardDisk) : @"harddiskTemplate",
@(MPIconCreated) : @"createdTemplate",
@(MPIconAddEntry) : @"addEntryTemplate",
@(MPIconContextTriangle) : @"contextTriangleTemplate",
@(MPIconKeyboard) : @"keyboardTemplate",
@(MPIconExpiredEntry): NSImageNameCaution,
@(MPIconExpiredGroup): NSImageNameCaution
};
@(MPIconExpiredEntry) : NSImageNameCaution,
@(MPIconExpiredGroup) : NSImageNameCaution
};
});
return imageNames;
}
@@ -177,7 +293,21 @@
return; // no url, no handler so no need to do anything
}
NSString *urlString = [NSString stringWithFormat:@"%@://%@/favicon.ico", url.scheme, url.host ? url.host : @""];
NSString *urlString;
MPFaviconDownloadMethod faviconDownloadMethod = (MPFaviconDownloadMethod)[NSUserDefaults.standardUserDefaults integerForKey:kMPSettingsKeyFaviconDownloadMethod];
switch(faviconDownloadMethod) {
case MPFaviconDownloadMethodGoogle:
urlString = [NSString stringWithFormat:@"https://www.google.com/s2/favicons?domain=%@", url.host ? url.host : @""];
break;
case MPFaviconDownloadMethodDuckDuckGo:
urlString = [NSString stringWithFormat:@"https://icons.duckduckgo.com/ip3/%@.ico", url.host ? url.host : @""];
break;
case MPFaviconDownloadMethodDirect:
default:
urlString = [NSString stringWithFormat:@"%@://%@/favicon.ico", url.scheme, url.host ? url.host : @""];
break;
}
NSURL *favIconURL = [NSURL URLWithString:urlString];
if(!favIconURL) {
/* call the handler with nil data */
@@ -187,15 +317,15 @@
NSURLSessionTask *task = [NSURLSession.sharedSession dataTaskWithURL:favIconURL completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if(error) {
handler(nil);
handler(nil);
}
else if([response respondsToSelector:@selector(statusCode)]
&& (200 == [(id)response statusCode])
&& data.length > 0) {
handler(data);
handler(data);
}
else {
handler(nil);
handler(nil);
}
}];
[task resume];

View File

@@ -23,7 +23,6 @@
#import "MPViewController.h"
@class MPDocument;
@class MPCollectionViewItem;
@interface MPIconSelectViewController : MPViewController <NSCollectionViewDelegate>

View File

@@ -239,7 +239,6 @@ typedef NS_ENUM(NSInteger, MPIconDownloadStatus) {
}
- (BOOL)collectionView:(NSCollectionView *)collectionView writeItemsAtIndexes:(NSIndexSet *)indexes toPasteboard:(NSPasteboard *)pasteboard {
NSLog(@"dragStart for indexes:%@", indexes);
[pasteboard declareTypes:@[(NSString *)kUTTypeText] owner:nil];
return YES;
}

View File

@@ -76,10 +76,6 @@ typedef NS_ENUM(NSUInteger, MPContentTab) {
return self;
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (NSResponder *)reconmendedFirstResponder {
return self.view;
}
@@ -104,6 +100,7 @@ typedef NS_ENUM(NSUInteger, MPContentTab) {
NSTabViewItem *groupTabItem = [self.tabView tabViewItemAtIndex:MPGroupTab];
NSView *groupTabView = groupTabItem.view;
[groupTabView addSubview:groupView];
[groupTabView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[groupView]|" options:0 metrics:nil views:views]];
[groupTabView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[groupView]|" options:0 metrics:nil views:views]];
groupTabItem.initialFirstResponder = groupView;
@@ -111,15 +108,15 @@ typedef NS_ENUM(NSUInteger, MPContentTab) {
[self.view layout];}
- (void)registerNotificationsForDocument:(MPDocument *)document {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(_didChangeCurrentItem:)
name:MPDocumentCurrentItemChangedNotification
object:document];
[NSNotificationCenter.defaultCenter addObserver:self
selector:@selector(_didChangeCurrentItem:)
name:MPDocumentCurrentItemChangedNotification
object:document];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(_willChangeModelProperty:)
name:MPDocumentWillChangeModelPropertyNotification
object:document];
[NSNotificationCenter.defaultCenter addObserver:self
selector:@selector(_willChangeModelProperty:)
name:MPDocumentWillChangeModelPropertyNotification
object:document];
self.entryViewController.observer = document;
self.itemImageView.modelChangeObserver = document;
@@ -154,7 +151,7 @@ typedef NS_ENUM(NSUInteger, MPContentTab) {
if(textView == self.notesTextView) {
name = NSLocalizedString(@"NOTES", "Displayed name when notes or part of notes was copied");
}
[[MPPasteBoardController defaultController] copyObjects:@[selectedString] overlayInfo:info name:name atView:self.view];
[MPPasteBoardController.defaultController copyObject:selectedString overlayInfo:info name:name atView:self.view];
return NO;
}
return YES;

View File

@@ -40,7 +40,7 @@
@property (strong) IBOutlet NSButton *matchTagsCheckBox;
@property (strong) IBOutlet NSButton *sendCommandForControlCheckBox;
@property (strong) IBOutlet NSButton *alwaysShowConfirmationBeforeAutotypeCheckBox;
/* Preview */
@property (strong) IBOutlet NSButton *enableQuicklookCheckBox;

View File

@@ -24,6 +24,7 @@
#import "MPSettingsHelper.h"
#import "MPIconHelper.h"
#import "MPAutotypeDoctor.h"
#import "MPConstants.h"
#import "DDHotKeyCenter.h"
#import "DDHotKey+MacPassAdditions.h"
@@ -67,7 +68,15 @@
[self.matchHostCheckBox bind:NSValueBinding toObject:defaultsController withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingsKeyAutotypeMatchHost] options:nil];
[self.matchTagsCheckBox bind:NSValueBinding toObject:defaultsController withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingsKeyAutotypeMatchTags] options:nil];
[self.sendCommandForControlCheckBox bind:NSValueBinding toObject:defaultsController withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingsKeySendCommandForControlKey] options:nil];
[self.sendCommandForControlCheckBox bind:NSValueBinding
toObject:defaultsController
withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingsKeySendCommandForControlKey]
options:nil];
[self.alwaysShowConfirmationBeforeAutotypeCheckBox bind:NSValueBinding
toObject:defaultsController
withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingsKeyGloablAutotypeAlwaysShowCandidateSelection]
options:nil];
[self _showKeyCodeMissingKeyWarning:NO];
[self _updateAccessabilityWarning];
@@ -121,4 +130,32 @@
- (void)runAutotypeDoctor:(id)sender {
[MPAutotypeDoctor.defaultDoctor runChecksAndPresentResults];
}
#pragma mark -
#pragma mark Keychain Actions
- (IBAction)RenewTouchIdKey:(id)sender {
NSData* publicKeyTag = [TouchIdUnlockPublicKeyTag dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *publicKeyQuery = @{
(id)kSecClass: (id)kSecClassKey,
(id)kSecAttrApplicationTag: publicKeyTag,
(id)kSecReturnRef: @YES,
};
OSStatus status = SecItemDelete((__bridge CFDictionaryRef)publicKeyQuery);
if (status != errSecSuccess) {
NSString* description = (__bridge NSString*)SecCopyErrorMessageString(status, NULL);
NSLog(@"Error while trying to delete public key from Keychain: %@", description);
}
NSData* privateKeyTag = [TouchIdUnlockPrivateKeyTag dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *privateKeyQuery = @{
(id)kSecClass: (id)kSecClassKey,
(id)kSecAttrApplicationTag: privateKeyTag,
(id)kSecReturnRef: @YES,
};
status = SecItemDelete((__bridge CFDictionaryRef)privateKeyQuery);
if (status != errSecSuccess) {
NSString* description = (__bridge NSString*)SecCopyErrorMessageString(status, NULL);
NSLog(@"Error while trying to delete private key from Keychain: %@", description);
}
}
@end

View File

@@ -165,7 +165,7 @@ static MPLockDaemon *_sharedInstance;
}
/* Create event handler if necessary */
if(!self.localEventHandler) {
self.localEventHandler = [NSEvent addLocalMonitorForEventsMatchingMask:NSAnyEventMask handler:^NSEvent *(NSEvent *theEvent) {
self.localEventHandler = [NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskAny handler:^NSEvent *(NSEvent *theEvent) {
self.lastLocalEventTime = NSDate.timeIntervalSinceReferenceDate;
return theEvent;
}];

View File

@@ -0,0 +1,18 @@
//
// MPNotificationPreferencesController.h
// MacPass
//
// Created by Michael Starke on 07.12.20.
// Copyright © 2020 HicknHack Software GmbH. All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import "MPPreferencesTab.h"
NS_ASSUME_NONNULL_BEGIN
@interface MPNotificationPreferencesController : NSViewController <MPPreferencesTab>
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,25 @@
//
// MPNotificationPreferencesController.m
// MacPass
//
// Created by Michael Starke on 07.12.20.
// Copyright © 2020 HicknHack Software GmbH. All rights reserved.
//
#import "MPNotificationPreferencesController.h"
@interface MPNotificationPreferencesController ()
@end
@implementation MPNotificationPreferencesController
- (NSImage *)image {
return [NSImage imageNamed:NSImageNameNetwork];
}
- (void)viewDidLoad {
[super viewDidLoad];
}
@end

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11134" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11134"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="MPNotificationPreferencesController">
<connections>
<outlet property="view" destination="Hz6-mo-xeY" id="0bl-1N-x8E"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customView id="Hz6-mo-xeY">
<rect key="frame" x="0.0" y="0.0" width="480" height="272"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
</customView>
</objects>
</document>

View File

@@ -225,6 +225,7 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell";
#pragma mark Notifications
- (void)registerNotificationsForDocument:(MPDocument *)document {
[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(_didAddGroup:) name:MPDocumentDidAddGroupNotification object:document];
[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(_didRevertDocument:) name:MPDocumentDidRevertNotification object:document];
}
- (void)clearSelection {
@@ -268,6 +269,9 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell";
[self.outlineView selectRowIndexes:[NSIndexSet indexSetWithIndex:groupRow] byExtendingSelection:NO];
[self.outlineView scrollRowToVisible:groupRow];
}
- (void)_didRevertDocument:(NSNotification *)notification {
[self clearSelection];
}
- (id)itemUnderMouse {
NSPoint mouseLocation = [self.outlineView.window mouseLocationOutsideOfEventStream];
@@ -320,10 +324,6 @@ NSString *const _MPOutlinveViewHeaderViewIdentifier = @"HeaderCell";
}];
}
- (BOOL)outlineView:(NSOutlineView *)outlineView shouldSelectItem:(id)item {
return ![self _itemIsRootNode:item];
}
- (void)outlineViewSelectionDidChange:(NSNotification *)notification {
MPDocument *document = self.windowController.document;
NSArray<KPKGroup *> *groups = self.currentTargetGroups;

View File

@@ -56,7 +56,7 @@
- (void)windowDidLoad {
[super windowDidLoad];
self.window.styleMask = NSBorderlessWindowMask;
self.window.styleMask = NSWindowStyleMaskBorderless;
self.window.alphaValue = 0;
self.window.opaque = NO;
self.window.hasShadow = YES;

View File

@@ -27,6 +27,8 @@
#import "MPSettingsHelper.h"
#import "MPDocument.h"
#import "MPModelChangeObserving.h"
#import "MPPrettyPasswordTransformer.h"
#import "MPFlagsHelper.h"
@@ -56,7 +58,6 @@ typedef NS_ENUM(NSUInteger, MPPasswordRating) {
@interface MPPasswordCreatorViewController ()
@property (nonatomic, copy) NSString *password;
@property (copy) NSString *generatedPassword;
@property (strong) IBOutlet NSTextField *passwordTextField;
@property (strong) IBOutlet NSTextField *passwordLengthTextField;
@@ -120,7 +121,7 @@ typedef NS_ENUM(NSUInteger, MPPasswordRating) {
[self.passwordLengthSlider bind:NSValueBinding toObject:self withKeyPath:NSStringFromSelector(@selector(passwordLength)) options:nil];
[self.passwordLengthTextField bind:NSValueBinding toObject:self withKeyPath:NSStringFromSelector(@selector(passwordLength)) options:nil];
[self.passwordTextField bind:NSValueBinding toObject:self withKeyPath:NSStringFromSelector(@selector(password)) options:nil];
[self.passwordTextField bind:NSValueBinding toObject:self withKeyPath:NSStringFromSelector(@selector(password)) options:@{ NSValueTransformerNameBindingOption: MPPrettyPasswordTransformerName }];
[self.entropyIndicator bind:NSValueBinding toObject:self withKeyPath:NSStringFromSelector(@selector(entropy)) options:nil];
[self.entropyTextField bind:NSValueBinding toObject:self withKeyPath:NSStringFromSelector(@selector(entropy)) options:nil];
@@ -161,7 +162,7 @@ typedef NS_ENUM(NSUInteger, MPPasswordRating) {
if(!self.allowsEntryDefaults || (nil == [self _currentEntryDefaults])) {
return; // We aren't using entry so just leave;
}
BOOL deleteEntryDefaults = MPIsFlagSetInOptions(NSAlternateKeyMask, [NSEvent modifierFlags]);
BOOL deleteEntryDefaults = MPIsFlagSetInOptions(NSEventModifierFlagOption, NSEvent.modifierFlags);
[self _updateSetDefaultsButton:deleteEntryDefaults];
}
@@ -193,7 +194,7 @@ typedef NS_ENUM(NSUInteger, MPPasswordRating) {
- (IBAction)_usePassword:(id)sender {
if(self.shouldCopyPasswordToPasteboardButton.state == NSOnState) {
[MPPasteBoardController.defaultController copyObjects:@[self.password]];
[MPPasteBoardController.defaultController copyObject:self.password];
}
KPKEntry *entry = self.representedObject;
if(entry && self.password.length > 0) {

View File

@@ -39,13 +39,15 @@
@interface MPPasswordEditWindowController : HNHUISheetWindowController <NSTextFieldDelegate>
@property (weak) IBOutlet HNHUISecureTextField *passwordTextField;
@property (weak) IBOutlet HNHUISecureTextField *passwordRepeatTextField;
@property (weak) IBOutlet NSPathControl *keyfilePathControl;
@property (weak) IBOutlet NSButton *togglePasswordButton;
@property (weak) IBOutlet NSTextField *errorTextField;
@property (weak) IBOutlet NSButton *changePasswordButton;
@property (weak) IBOutlet NSButton *hasPasswordSwitchButton;
@property (strong) IBOutlet HNHUISecureTextField *passwordTextField;
@property (strong) IBOutlet HNHUISecureTextField *passwordRepeatTextField;
@property (strong) IBOutlet NSPathControl *keyfilePathControl;
@property (strong) IBOutlet NSButton *togglePasswordButton;
@property (strong) IBOutlet NSTextField *passwordErrorTextField;
@property (strong) IBOutlet NSTextField *keyErrorTextField;
@property (strong) IBOutlet NSButton *changePasswordButton;
@property (strong) IBOutlet NSButton *hasPasswordSwitchButton;
@property (strong) IBOutlet NSGridView *gridView;
- (IBAction)clearKey:(id)sender;
- (IBAction)generateKey:(id)sender;

View File

@@ -22,17 +22,34 @@
#import "MPPasswordEditWindowController.h"
#import "MPDocument.h"
#import "MPPathControl.h"
#import "HNHUi/HNHUi.h"
#import "KeePassKit/KeePassKit.h"
typedef NS_ENUM(NSUInteger, MPPasswordEditPasswordError) {
MPPasswordEditPasswordErrorNone,
MPPasswordEditPasswordErrorNoPassword,
MPPasswordEditPasswordErrorRepeatMissmatch
};
typedef NS_ENUM(NSUInteger, MPPasswordEditKeyError) {
MPPasswordEditKeyErrorNone,
MPPasswordEditKeyErrorNoKey,
MPPasswordEditKeyErrorNotReachable,
MPPasswordEditKeyErrorIsCurrentDatabase,
MPPasswordEditKeyErrorIsKeePassDatabase,
};
@interface MPPasswordEditWindowController ()
@property (nonatomic, assign) BOOL showPassword;
@property (nonatomic, assign) BOOL enablePassword;
@property (nonatomic, assign) BOOL hasValidPasswordOrKey;
@property (nonatomic, weak) NSURL *keyURL;
@property (weak) NSGridRow *passwordErrorGridRow;
@property (weak) NSGridRow *keyErrorGridRow;
@end
@@ -53,10 +70,14 @@
- (void)windowDidLoad {
[super windowDidLoad];
[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(_didChangeKeyURL:) name:MPPathControlDidSetURLNotification object:self.keyfilePathControl];
[self.togglePasswordButton bind:NSValueBinding toObject:self withKeyPath:NSStringFromSelector(@selector(showPassword)) options:nil];
self.window.defaultButtonCell = self.changePasswordButton.cell;
MPDocument *document = self.document;
self.enablePassword = document.compositeKey.hasPassword;
self.enablePassword = [document.compositeKey hasKeyOfClass:KPKPasswordKey.class];
self.passwordErrorGridRow = [self.gridView cellForView:self.passwordErrorTextField].row;
self.keyErrorGridRow = [self.gridView cellForView:self.keyErrorTextField].row;
}
- (void)updateView {
@@ -77,9 +98,8 @@
[self.togglePasswordButton bind:NSEnabledBinding toObject:self withKeyPath:enablePasswordKeyPath options:nil];
[self.passwordRepeatTextField bind:NSEnabledBinding toObject:self withKeyPath:showPasswordKeyPath options:negateOption];
[self.passwordRepeatTextField bind:NSEnabledBinding toObject:self withKeyPath:enablePasswordKeyPath options:nil];
[self.errorTextField bind:NSHiddenBinding toObject:self withKeyPath:hasValidPasswordOrKeyKeyPath options:nil];
[self.changePasswordButton bind:NSEnabledBinding toObject:self withKeyPath:hasValidPasswordOrKeyKeyPath options:nil];
[self.keyfilePathControl bind:NSValueBinding toObject:self withKeyPath:NSStringFromSelector(@selector(keyURL)) options:nil];
self.passwordRepeatTextField.delegate = self;
self.passwordTextField.delegate = self;
@@ -98,10 +118,7 @@
[self _verifyPasswordAndKey];
}
}
- (void)setKeyURL:(NSURL *)keyURL {
_keyURL = keyURL;
[self _verifyPasswordAndKey];
}
- (void)setEnablePassword:(BOOL)enablePassword {
if(_enablePassword != enablePassword) {
_enablePassword = enablePassword;
@@ -110,10 +127,12 @@
NSString *repeatPlaceHolder = _enablePassword ? NSLocalizedString(@"PASSWORD_INPUT_REPEAT_PASSWORD", "Placeholder for the repeat password field to aks for the repeated password") : NSLocalizedString(@"PASSWORD_INPUT_NO_PASSWORD", "Placeholder for the repeat password input if passwords are disabled");
self.passwordTextField.placeholderString = passwordPlaceHolder;
self.passwordRepeatTextField.placeholderString = repeatPlaceHolder;
[self _verifyPasswordAndKey];
}
#pragma mark Actions
- (IBAction)save:(id)sender {
/* TODO: Move to a more generalized aproach to initalize the composite key and set it via a MPDocument API */
const BOOL hasPassword = HNHUIBoolForState(self.hasPasswordSwitchButton.state);
NSString *password = hasPassword ? self.passwordTextField.stringValue : nil;
MPDocument *document = self.document;
@@ -126,7 +145,7 @@
}
- (IBAction)clearKey:(id)sender {
self.keyURL = nil;
self.keyfilePathControl.URL = nil;
}
- (IBAction)generateKey:(id)sender {
@@ -138,12 +157,12 @@
savePanel.canCreateDirectories = YES;
savePanel.title = NSLocalizedString(@"SAVE_KEYFILE", "Button title to save the generated key file");
[savePanel beginWithCompletionHandler:^(NSInteger result) {
if(result == NSFileHandlingPanelOKButton) {
if(result == NSModalResponseOK) {
NSURL *keyURL = [savePanel URL];
NSError *error;
BOOL saveOk = [data writeToURL:keyURL options:NSDataWritingAtomic error:&error];
if(saveOk) {
self.keyURL = keyURL;
self.keyfilePathControl.URL = keyURL;
}
}
}];
@@ -155,43 +174,128 @@
[self _verifyPasswordAndKey];
}
- (void)_verifyPasswordAndKey {
NSString *password = self.passwordTextField.stringValue;
NSString *repeat = self.passwordRepeatTextField.stringValue;
BOOL hasKey = (self.keyURL != nil);
BOOL keyOk = YES;
if(hasKey) {
keyOk = [self.keyURL checkResourceIsReachableAndReturnError:nil];
}
BOOL hasPassword = password.kpk_isNotEmpty;
if(!self.showPassword) {
hasPassword |= repeat.kpk_isNotEmpty;
}
BOOL passwordOk = YES;
if(hasPassword ) {
passwordOk = [password isEqualToString:repeat] || self.showPassword;
}
BOOL hasPasswordOrKey = (hasKey || hasPassword);
keyOk = hasKey ? keyOk : YES;
passwordOk = hasPassword ? passwordOk : YES;
self.hasValidPasswordOrKey = hasPasswordOrKey && passwordOk && keyOk;
if(!hasPasswordOrKey) {
self.errorTextField.textColor = NSColor.controlTextColor;
self.errorTextField.stringValue = NSLocalizedString(@"WARNING_NO_PASSWORD_OR_KEYFILE", "No Key or Password");
return; // all done
}
self.errorTextField.textColor = NSColor.redColor;
if(!passwordOk && !keyOk ) {
self.errorTextField.stringValue = NSLocalizedString(@"ERROR_PASSWORD_MISSMATCH_INVALID_KEYFILE", "Passwords do not match, keyfile is invalid");
}
else if(!passwordOk) {
self.errorTextField.stringValue = NSLocalizedString(@"ERROR_PASSWORD_MISSMATCH", "Passwords do not match");
}
else {
self.errorTextField.stringValue = NSLocalizedString(@"ERROR_INVALID_KEYFILE", "Keyfile not valid");
#pragma mark Notifications
- (void)_didChangeKeyURL:(NSNotification *)notification {
if(notification.object != self.keyfilePathControl) {
return;
}
[self _verifyPasswordAndKey];
}
#pragma mark UI update
- (void)_verifyPasswordAndKey {
self.passwordErrorGridRow.hidden = YES;
self.keyErrorGridRow.hidden = YES;
self.keyErrorTextField.stringValue = @"";
self.passwordErrorTextField.stringValue = @"";
MPPasswordEditKeyError keyError = [self _verifyKey];
MPPasswordEditPasswordError passwordError = [self _verifyPassword];
self.keyErrorTextField.textColor = NSColor.controlTextColor;
self.passwordErrorTextField.textColor = NSColor.controlTextColor;
if(keyError == MPPasswordEditKeyErrorNoKey && passwordError == MPPasswordEditPasswordErrorNoPassword) {
self.passwordErrorTextField.stringValue = NSLocalizedString(@"WARNING_NO_PASSWORD", "Warning if no password is set when chaning the password");
self.passwordErrorGridRow.hidden = NO;
self.keyErrorTextField.stringValue = NSLocalizedString(@"WARNING_NO_KEYFILE", "Warning tha no key file is set when chaning the password");
self.keyErrorGridRow.hidden = NO;
return;
}
switch(keyError) {
case MPPasswordEditKeyErrorNotReachable:
self.keyErrorTextField.stringValue = NSLocalizedString(@"ERROR_KEYFILE_NOT_FOUND", "Keyfile was not found");
self.keyErrorTextField.textColor = NSColor.redColor;
self.keyErrorGridRow.hidden = NO;
break;
case MPPasswordEditKeyErrorIsCurrentDatabase:
self.keyErrorTextField.stringValue = NSLocalizedString(@"WARNING_CURRENT_DATABASE_FILE_SELECTED_AS_KEY_FILE", "Error message displayed when the current database file is also set as the key file");
self.keyErrorTextField.textColor = NSColor.redColor;
self.keyErrorGridRow.hidden = NO;
break;
case MPPasswordEditKeyErrorIsKeePassDatabase:
self.keyErrorTextField.stringValue = NSLocalizedString(@"WARNING_DATABASE_FILE_SELECTED_AS_KEY_FILE", "Error message displayed when a keepass database file is set as the key file");
self.keyErrorTextField.textColor = NSColor.redColor;
self.keyErrorGridRow.hidden = NO;
break;
case MPPasswordEditKeyErrorNoKey:
if(!self.enablePassword) {
self.keyErrorTextField.stringValue = NSLocalizedString(@"WARNING_NO_KEYFILE", "No key file is set");
self.keyErrorGridRow.hidden = NO;
}
keyError = MPPasswordEditKeyErrorNone; // remove the error
break;
case MPPasswordEditKeyErrorNone:
break;
}
switch(passwordError) {
case MPPasswordEditPasswordErrorRepeatMissmatch:
self.passwordErrorTextField.stringValue = NSLocalizedString(@"ERROR_PASSWORD_MISSMATCH", "Passwords do not match");
self.passwordErrorTextField.textColor = NSColor.redColor;
self.passwordErrorGridRow.hidden = NO;
break;
case MPPasswordEditPasswordErrorNone:
case MPPasswordEditPasswordErrorNoPassword:
break;
}
self.hasValidPasswordOrKey = (passwordError == MPPasswordEditPasswordErrorNone && keyError == MPPasswordEditKeyErrorNone);
}
- (MPPasswordEditKeyError)_verifyKey {
NSURL *keyURL = self.keyfilePathControl.URL;
if(!keyURL) {
return MPPasswordEditKeyErrorNoKey;
}
if(![keyURL checkResourceIsReachableAndReturnError:nil]) {
return MPPasswordEditKeyErrorNotReachable;
}
/* TODO: exten KPKFileKey to do database checks internally */
NSDocument *document = (NSDocument *)self.document;
NSData *keyFileData = [NSData dataWithContentsOfURL:keyURL];
KPKFileVersion keyFileVersion = [KPKFormat.sharedFormat fileVersionForData:keyFileData];
if(keyFileVersion.format != KPKDatabaseFormatUnknown) {
if([document.fileURL isEqual:keyURL]) {
return MPPasswordEditKeyErrorIsCurrentDatabase;
}
return MPPasswordEditKeyErrorIsKeePassDatabase;
}
/* FIXME: check xml key */
return MPPasswordEditKeyErrorNone;
}
- (MPPasswordEditPasswordError)_verifyPassword {
if(!self.enablePassword) {
return MPPasswordEditPasswordErrorNone;
}
NSString *password = self.passwordTextField.stringValue;
NSString *repeat = self.passwordRepeatTextField.stringValue;
if(self.showPassword) {
if(password.kpk_isNotEmpty) {
return MPPasswordEditPasswordErrorNone;
}
return MPPasswordEditPasswordErrorNoPassword;
}
if(!password.kpk_isNotEmpty && !repeat.kpk_isNotEmpty) {
return MPPasswordEditPasswordErrorNoPassword;
}
if(![password isEqualToString:repeat]) {
return MPPasswordEditPasswordErrorRepeatMissmatch;
}
return MPPasswordEditPasswordErrorNone;
}
@end

View File

@@ -21,14 +21,14 @@
//
#import "MPViewController.h"
#import "KeePassKit/KeePassKit.h"
@class KPKCompositeKey;
@interface MPPasswordInputController : MPViewController <NSTouchBarDelegate>
typedef BOOL (^passwordInputCompletionBlock)(NSString *password, NSURL *keyURL, BOOL didCancel, NSError *__autoreleasing*error);
typedef BOOL (^passwordInputCompletionBlock)(KPKCompositeKey *key, NSURL* keyFileURL, BOOL didCancel, NSError *__autoreleasing*error);
- (void)requestPasswordWithCompletionHandler:(passwordInputCompletionBlock)completionHandler;
- (void)requestPasswordWithMessage:(NSString *)message cancelLabel:(NSString *)cancelLabel completionHandler:(passwordInputCompletionBlock)completionHandler;

View File

@@ -27,6 +27,9 @@
#import "MPSettingsHelper.h"
#import "MPPathControl.h"
#import "MPTouchBarButtonCreator.h"
#import "MPSettingsHelper.h"
#import "MPConstants.h"
#import "MPTouchIdCompositeKeyStore.h"
#import "HNHUi/HNHUi.h"
@@ -44,6 +47,8 @@
@property (weak) IBOutlet NSButton *enablePasswordCheckBox;
@property (weak) IBOutlet NSButton *unlockButton;
@property (weak) IBOutlet NSButton *cancelButton;
@property (weak) IBOutlet NSButton *touchIdButton;
@property (weak) IBOutlet NSButton *touchIdEnabledButton;
@property (copy) NSString *message;
@property (copy) NSString *cancelLabel;
@@ -81,6 +86,13 @@
[self.enablePasswordCheckBox bind:NSValueBinding toObject:self withKeyPath:NSStringFromSelector(@selector(enablePassword)) options:nil];
[self.togglePasswordButton bind:NSEnabledBinding toObject:self withKeyPath:NSStringFromSelector(@selector(enablePassword)) options:nil];
[self.passwordTextField bind:NSEnabledBinding toObject:self withKeyPath:NSStringFromSelector(@selector(enablePassword)) options:nil];
NSUserDefaultsController *defaultsController = [NSUserDefaultsController sharedUserDefaultsController];
[self.touchIdEnabledButton bind:NSValueBinding toObject:defaultsController withKeyPath:[MPSettingsHelper defaultControllerPathForKey:kMPSettingsKeyEntryTouchIdEnabled] options:nil];
self.touchIdEnabledButton.hidden = true;
if (@available(macOS 10.13.4, *)) {
self.touchIdEnabledButton.hidden = false;
[self _touchIdUpdateToolTip];
}
[self _reset];
}
@@ -95,10 +107,6 @@
[self _reset];
}
- (void)requestPasswordWithCompletionHandler:(passwordInputCompletionBlock)completionHandler {
[self requestPasswordWithMessage:nil cancelLabel:nil completionHandler:completionHandler];
}
#pragma mark Properties
- (void)setEnablePassword:(BOOL)enablePassword {
if(_enablePassword != enablePassword) {
@@ -127,8 +135,24 @@
NSString *password = self.enablePassword ? self.passwordTextField.stringValue : nil;
BOOL cancel = (sender == self.cancelButton);
BOOL result = self.completionHandler(password, self.keyPathControl.URL, cancel, &error);
if(cancel || result) {
NSURL* keyURL = self.keyPathControl.URL;
NSData *keyFileData = keyURL ? [NSData dataWithContentsOfURL:keyURL] : nil;
KPKKey* passwordKey = [KPKKey keyWithPassword:password];
KPKKey* fileKey = [KPKKey keyWithKeyFileData:keyFileData];
KPKCompositeKey* compositeKey = [[KPKCompositeKey alloc] init];
[compositeKey addKey:passwordKey];
[compositeKey addKey:fileKey];
/* After the completion handler finished we no longer have a windowController set */
NSString* documentKey = NULL;
bool documentKeyValid = [self _touchIdGetKeyForCurrentDocument:&documentKey];
BOOL result = self.completionHandler(compositeKey, keyURL, cancel, &error);
if(result) {
if(documentKeyValid) {
[self _touchIdUpdateKeyForCurrentDocument:compositeKey forDocumentKey:documentKey];
}
return;
}
if(cancel) {
return;
}
[self _showError:error];
@@ -138,6 +162,203 @@
}
}
- (void) _touchIdUpdateKeyForCurrentDocument: (KPKCompositeKey*)compositeKey forDocumentKey: (NSString*) documentKey{
NSData* encryptedKey = [self _touchIdEncryptCompositeKey:compositeKey];
[MPTouchIdCompositeKeyStore.defaultStore save:encryptedKey forDocumentKey:documentKey];
}
- (void) _touchIdCreateAndAddRSAKeyPair {
CFErrorRef error = NULL;
NSString* publicKeyLabel = @"MacPass TouchID Feature Public Key";
NSString* privateKeyLabel = @"MacPass TouchID Feature Private Key";
NSData* publicKeyTag = [TouchIdUnlockPublicKeyTag dataUsingEncoding:NSUTF8StringEncoding];
NSData* privateKeyTag = [TouchIdUnlockPrivateKeyTag dataUsingEncoding:NSUTF8StringEncoding];
SecAccessControlRef access = NULL;
if (@available(macOS 10.13.4, *)) {
SecAccessControlCreateFlags flags = kSecAccessControlBiometryCurrentSet;
if (@available(macOS 10.15, *)) {
flags |= kSecAccessControlWatch | kSecAccessControlOr;
}
access = SecAccessControlCreateWithFlags(kCFAllocatorDefault,
kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
flags,
&error);
if(access == NULL) {
NSError *err = CFBridgingRelease(error);
NSLog(@"Error while trying to create AccessControl for TouchID unlock feature: %@", [err description]);
return;
}
NSDictionary* attributes = @{
(id)kSecAttrKeyType: (id)kSecAttrKeyTypeRSA,
(id)kSecAttrKeySizeInBits: @2048,
(id)kSecAttrSynchronizable: @NO,
(id)kSecPrivateKeyAttrs:
@{ (id)kSecAttrIsPermanent: @YES,
(id)kSecAttrApplicationTag: privateKeyTag,
(id)kSecAttrLabel: privateKeyLabel,
(id)kSecAttrAccessControl: (__bridge id)access
},
(id)kSecPublicKeyAttrs:
@{ (id)kSecAttrIsPermanent: @YES,
(id)kSecAttrApplicationTag: publicKeyTag,
(id)kSecAttrLabel: publicKeyLabel,
},
};
SecKeyRef result = SecKeyCreateRandomKey((__bridge CFDictionaryRef)attributes, &error);
if(result == NULL) {
NSError *err = CFBridgingRelease(error);
NSLog(@"Error while trying to create a RSA keypair for TouchID unlock feature: %@", [err description]);
}
else {
CFRelease(result);
}
}
else {
return;
}
}
- (NSData*) _touchIdEncryptCompositeKey: (KPKCompositeKey*) compositeKey {
NSData* encryptedKey = nil;
NSData* keyData = [NSKeyedArchiver archivedDataWithRootObject:compositeKey];
NSData* tag = [TouchIdUnlockPublicKeyTag dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *getquery = @{
(id)kSecClass: (id)kSecClassKey,
(id)kSecAttrApplicationTag: tag,
(id)kSecReturnRef: @YES,
};
SecKeyRef publicKey = NULL;
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)getquery, (CFTypeRef *)&publicKey);
if (status != errSecSuccess) {
[self _touchIdCreateAndAddRSAKeyPair];
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)getquery, (CFTypeRef *)&publicKey);
if (status != errSecSuccess) {
NSString* description = (__bridge NSString*)SecCopyErrorMessageString(status, NULL);
NSLog(@"Error while trying to query public key from Keychain: %@", description);
return nil;
}
}
SecKeyAlgorithm algorithm = kSecKeyAlgorithmRSAEncryptionOAEPSHA256AESGCM;
BOOL canEncrypt = SecKeyIsAlgorithmSupported(publicKey, kSecKeyOperationTypeEncrypt, algorithm);
if(canEncrypt) {
CFErrorRef error = NULL;
encryptedKey = (NSData*)CFBridgingRelease(SecKeyCreateEncryptedData(publicKey, algorithm, (__bridge CFDataRef)keyData, &error));
if (!encryptedKey) {
NSError *err = CFBridgingRelease(error);
NSLog(@"Error while trying to decrypt the CompositeKey for TouchID unlock: %@", [err description]);
}
}
else {
NSLog(@"The key retreived from the Keychain is unable to encrypt data");
}
if (publicKey) {
CFRelease(publicKey);
}
return encryptedKey;
}
- (KPKCompositeKey*) _touchIdDecryptCompositeKey: (NSData*) encryptedKey {
KPKCompositeKey* result = nil;
if(encryptedKey != nil) {
NSData* tag = [TouchIdUnlockPrivateKeyTag dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *queryPrivateKey = @{
(id)kSecClass: (id)kSecClassKey,
(id)kSecAttrApplicationTag: tag,
(id)kSecAttrKeyType: (id)kSecAttrKeyTypeRSA,
(id)kSecReturnRef: @YES,
};
SecKeyRef privateKey = NULL;
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)queryPrivateKey, (CFTypeRef *)&privateKey);
if (status == errSecSuccess) {
SecKeyAlgorithm algorithm = kSecKeyAlgorithmRSAEncryptionOAEPSHA256AESGCM;
BOOL canDecrypt = SecKeyIsAlgorithmSupported(privateKey, kSecKeyOperationTypeDecrypt, algorithm);
if(canDecrypt) {
CFErrorRef error = NULL;
NSData* clearText = (NSData*)CFBridgingRelease(SecKeyCreateDecryptedData(privateKey, algorithm, (__bridge CFDataRef)encryptedKey, &error));
if (clearText) {
result = [NSKeyedUnarchiver unarchiveObjectWithData:clearText];
}
else {
NSError *err = CFBridgingRelease(error);
NSLog(@"Error while trying to decrypt password for TouchID unlock: %@", [err description]);
}
}
else {
NSLog(@"Key does not support decryption");
}
}
else {
NSString* description = (__bridge NSString*)SecCopyErrorMessageString(status, NULL);
NSLog(@"Error while trying to retrive private key for decryption: %@", description);
}
if (privateKey) {
CFRelease(privateKey);
}
}
return result;
}
- (bool) _touchIdGetKeyForCurrentDocument: (NSString**) result {
*result = NULL;
NSDocument* currentDocument = self.windowController.document;
if(currentDocument != NULL && currentDocument.fileURL != NULL && currentDocument.fileURL.lastPathComponent != NULL) {
*result = [NSString stringWithFormat:kMPSettingsKeyEntryTouchIdDatabaseEncryptedKeyFormat, currentDocument.fileURL.lastPathComponent];
return true;
}
return false;
}
- (bool) _touchIdIsUnlockAvailable {
NSData* unused = NULL;
bool encryptedKeyAvailableForDocument = [self _touchIdGetEncrypedKeyMaterial:&unused];
return encryptedKeyAvailableForDocument;
}
- (bool) _touchIdGetEncrypedKeyMaterial: (NSData**) result {
NSString* documentKey = NULL;
*result = NULL;
if(![self _touchIdGetKeyForCurrentDocument:&documentKey]) {
return false;
}
return [MPTouchIdCompositeKeyStore.defaultStore load:result forDocumentKey:documentKey];
}
- (IBAction)unlockWithTouchID:(id)sender {
NSData* encryptedKey = NULL;
if(![self _touchIdGetEncrypedKeyMaterial:&encryptedKey]) {
[self.touchIdButton setEnabled:false];
return;
}
KPKCompositeKey* compositeKey = [self _touchIdDecryptCompositeKey:encryptedKey];
if(compositeKey == NULL) {
[self.touchIdButton setEnabled:false];
return;
}
NSError* error;
bool success = self.completionHandler(compositeKey, NULL, false, &error);
if(success) {
return;
}
[self.touchIdButton setEnabled:false];
[self _showError:error];
}
- (IBAction)touchIdEnabledChanged:(id)sender {
[self _touchIdUpdateToolTip];
}
- (void) _touchIdUpdateToolTip {
switch(self.touchIdEnabledButton.state) {
case NSControlStateValueOn:
self.touchIdEnabledButton.toolTip = NSLocalizedString(@"TOOLTIP_TOUCHID_ENABELD", @"Tooltip displayed when TouchID is is fully enabeld");
case NSControlStateValueOff:
self.touchIdEnabledButton.toolTip = NSLocalizedString(@"TOOLTIP_TOUCHID_DISABLED", @"Tooltip displayed when TouchID is disabled");
case NSControlStateValueMixed:
default:
self.touchIdEnabledButton.toolTip = NSLocalizedString(@"TOOLTIP_TOUCHID_TRANSIENT", @"Tooltip displayed when TouchID is in transient (inmemory) mode");
}
}
- (IBAction)resetKeyFile:(id)sender {
/* If the reset was triggered by ourselves we want to preselect the keyfile */
if(sender == self) {
@@ -153,6 +374,9 @@
self.enablePassword = YES;
self.passwordTextField.stringValue = @"";
self.messageInfoTextField.hidden = (nil == self.message);
self.touchIdButton.hidden = ![self _touchIdIsUnlockAvailable];
[self.touchIdButton setEnabled:true];
if(self.message) {
self.messageInfoTextField.stringValue = self.message;
self.messageImageView.image = [NSImage imageNamed:NSImageNameInfo];
@@ -209,9 +433,7 @@
- (void)toggleShowPassword {
self.showPassword = !self.showPassword;
if (@available(macOS 10.12.2, *)) {
_showPasswordButton.bezelColor = self.showPassword ? [NSColor selectedControlColor] : [NSColor controlColor];
}
self.showPasswordButton.bezelColor = self.showPassword ? [NSColor selectedControlColor] : [NSColor controlColor];
}
- (void)_didSetKeyURL:(NSNotification *)notification {
@@ -238,5 +460,4 @@
}
}
@end

View File

@@ -55,8 +55,8 @@ FOUNDATION_EXPORT NSString *const MPPasteBoardControllerDidClearClipboard;
- (void)stashObjects;
- (void)restoreObjects;
- (void)copyObjects:(NSArray<id<NSPasteboardWriting>> *)objects;
- (void)copyObjectsWithoutTimeout:(NSArray<id<NSPasteboardWriting>> *)objects;
- (void)copyObject:(id<NSPasteboardWriting>)objects;
- (void)copyObjectWithoutTimeout:(id<NSPasteboardWriting>)objects;
/**
The pastboard controller will copy the object to the clipboard, display an appropriate overlay image
@@ -65,11 +65,11 @@ FOUNDATION_EXPORT NSString *const MPPasteBoardControllerDidClearClipboard;
to the clipboard. If the clipboard is used internally (e.g. for autotype) you should call copyObjects:
or even copyObjectsWithoutTimeout:
@param objects object so be copied
@param object object so be copied
@param overlayInfoType infotype discribing what is copied
@param name a custom name
@param view the view that initiated the copy action
*/
- (void)copyObjects:(NSArray<id<NSPasteboardWriting>> *)objects overlayInfo:(MPPasteboardOverlayInfoType)overlayInfoType name:(NSString *)name atView:(NSView *)view;
- (void)copyObject:(id<NSPasteboardWriting>)object overlayInfo:(MPPasteboardOverlayInfoType)overlayInfoType name:(NSString *)name atView:(NSView *)view;
@end

View File

@@ -28,6 +28,14 @@
NSString *const MPPasteBoardControllerDidCopyObjects = @"com.hicknhack.macpass.MPPasteBoardControllerDidCopyObjects";
NSString *const MPPasteBoardControllerDidClearClipboard = @"com.hicknhack.macpass.MPPasteBoardControllerDidClearClipboard";
/*
Pasteboard types. See NSPasteboard.org for refernce
*/
NSString *const MPPasteBoardTypeTransient = @"org.nspasteboard.TransientType";
NSString *const MPPasteBoardTypeConcealed = @"org.nspasteboard.ConcealedType";
NSString *const MPPasteBoardTypeAutoGenerated = @"org.nspasteboard.AutoGeneratedType";
NSString *const MPPasteBoardTypeSource = @"org.nspasteboard.source";
@interface MPPasteBoardController ()
@property (assign) BOOL isEmpty;
@@ -72,6 +80,9 @@ NSString *const MPPasteBoardControllerDidClearClipboard = @"com.hicknhack.macpas
- (void)stashObjects {
self.stashedObjects = [NSMutableArray array];
for(NSPasteboardItem *item in NSPasteboard.generalPasteboard.pasteboardItems) {
if(![self _shouldStashPasteboardItem:item]) {
continue; // skip item we should not stash
}
NSPasteboardItem *newItem = [[NSPasteboardItem alloc] init];
for (NSString *type in item.types) {
/* mutable copy to ensure actual deep copy */
@@ -93,9 +104,11 @@ NSString *const MPPasteBoardControllerDidClearClipboard = @"com.hicknhack.macpas
}
}
- (void)copyObjects:(NSArray<id<NSPasteboardWriting>> *)objects {
[self copyObjectsWithoutTimeout:objects];
- (void)copyObject:(id<NSPasteboardWriting>)object {
[self copyObjectWithoutTimeout:object];
if(self.clearTimeout != 0) {
/* add transient since we do clear after delay */
[NSPasteboard.generalPasteboard setData:nil forType:MPPasteBoardTypeTransient];
[NSNotificationCenter.defaultCenter postNotificationName:MPPasteBoardControllerDidCopyObjects object:self];
/* cancel old timer */
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(_clearPasteboardContents) object:nil];
@@ -104,23 +117,20 @@ NSString *const MPPasteBoardControllerDidClearClipboard = @"com.hicknhack.macpas
}
}
- (void)copyObjectsWithoutTimeout:(NSArray<id<NSPasteboardWriting>> *)objects {
if(@available(macOS 10.12, *)) {
NSPasteboardContentsOptions options = [NSUserDefaults.standardUserDefaults boolForKey:kMPSettingsKeyPreventUniversalClipboard] ? NSPasteboardContentsCurrentHostOnly : 0;
[NSPasteboard.generalPasteboard prepareForNewContentsWithOptions:options];
}
else {
[NSPasteboard.generalPasteboard clearContents];
}
[NSPasteboard.generalPasteboard writeObjects:objects];
- (void)copyObjectWithoutTimeout:(id<NSPasteboardWriting>)object {
NSPasteboardContentsOptions options = [NSUserDefaults.standardUserDefaults boolForKey:kMPSettingsKeyPreventUniversalClipboard] ? NSPasteboardContentsCurrentHostOnly : 0;
[NSPasteboard.generalPasteboard prepareForNewContentsWithOptions:options];
[NSPasteboard.generalPasteboard writeObjects:@[object]];
[NSPasteboard.generalPasteboard setData:nil forType:MPPasteBoardTypeConcealed]; // mark as concealed
[NSPasteboard.generalPasteboard setString:NSRunningApplication.currentApplication.bundleIdentifier forType:MPPasteBoardTypeSource]; // set source
self.isEmpty = NO;
}
- (void)copyObjects:(NSArray<id<NSPasteboardWriting>> *)objects overlayInfo:(MPPasteboardOverlayInfoType)overlayInfoType name:(NSString *)name atView:(NSView *)view{
if(!objects) {
- (void)copyObject:(id<NSPasteboardWriting>)object overlayInfo:(MPPasteboardOverlayInfoType)overlayInfoType name:(NSString *)name atView:(NSView *)view{
if(!object) {
return;
}
[MPPasteBoardController.defaultController copyObjects:objects];
[MPPasteBoardController.defaultController copyObject:object];
NSImage *infoImage = nil;
NSString *infoText = nil;
switch(overlayInfoType) {
@@ -190,4 +200,22 @@ NSString *const MPPasteBoardControllerDidClearClipboard = @"com.hicknhack.macpas
options:nil];
}
- (BOOL)_shouldStashPasteboardItem:(NSPasteboardItem *)item {
for(NSString *type in item.types) {
if([type isEqualToString:MPPasteBoardTypeConcealed]) {
return NO;
}
if([type isEqualToString:MPPasteBoardTypeTransient]) {
return NO;
}
if([type isEqualToString:MPPasteBoardTypeSource]) {
NSString *sourceBundle = [item stringForType:type];
if([NSRunningApplication.currentApplication.bundleIdentifier isEqualToString:sourceBundle]) {
return NO;
}
}
}
return YES;
}
@end

View File

@@ -75,23 +75,6 @@ NSString *const MPPathControlDidSetURLNotification = @"MPPathControlDidSetURLNot
}];
}
- (void)pathControl:(NSPathControl *)pathControl willPopUpMenu:(NSMenu *)menu {
if(pathControl != self) {
return;
}
if(@available(macOS 10.11, *)) {
// skip
}
else {
if(!self.URL) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(50 * NSEC_PER_MSEC)), dispatch_get_main_queue(), ^{
[menu cancelTracking];
});
[self showOpenPanel:self];
}
}
}
- (void)pathControl:(NSPathControl *)pathControl willDisplayOpenPanel:(NSOpenPanel *)openPanel {
openPanel.animationBehavior = NSWindowAnimationBehaviorDocumentWindow;
openPanel.canChooseDirectories = NO;

View File

@@ -26,12 +26,13 @@
typedef NS_ENUM(NSUInteger, MPPreferencesTab) {
MPPreferencesTabGeneral,
MPPreferencesTabIntegration,
MPPreferencesTabWorkflow,
MPPreferencesTabUpdate,
MPPreferencesTabPlugins
};
@interface MPPreferencesWindowController : NSWindowController <NSToolbarDelegate>
@interface MPPreferencesWindowController : NSWindowController
- (void)showPreferences;
- (void)showPreferencesTab:(MPPreferencesTab)tab;

View File

@@ -29,14 +29,11 @@
#import "MPWorkflowPreferencesController.h"
#import "MPUpdatePreferencesController.h"
#import "MPPluginPreferencesController.h"
#import "MPTabViewController.h"
@interface MPPreferencesWindowController () {
NSString *lastIdentifier;
}
@interface MPPreferencesWindowController ()
@property (strong, nonatomic) NSMutableDictionary *preferencesController;
@property (strong, nonatomic) NSMutableDictionary *toolbarItems;
@property (strong) NSArray *defaultToolbarItems;
@property (strong) MPTabViewController *tabViewController;
@end
@@ -49,67 +46,60 @@
-(id)init {
self = [super initWithWindow:nil];
if(self) {
NSToolbar *tb = [[NSToolbar alloc] initWithIdentifier:@"PreferencesToolBar"];
tb.allowsUserCustomization = NO;
tb.displayMode = NSToolbarDisplayModeIconAndLabel;
_preferencesController = [[NSMutableDictionary alloc] initWithCapacity:5];
_toolbarItems = [[NSMutableDictionary alloc] initWithCapacity:5];
lastIdentifier = nil;
_tabViewController = [[MPTabViewController alloc] init];
_tabViewController.tabStyle = NSTabViewControllerTabStyleToolbar;
_tabViewController.transitionOptions = NSViewControllerTransitionNone | NSViewControllerTransitionAllowUserInteraction;
self.contentViewController = self.tabViewController;
_tabViewController.willSelectTabHandler = ^void(NSTabViewItem *item) {
if([item.viewController respondsToSelector:@selector(willShowTab)]) {
[(id<MPPreferencesTab>)item.viewController willShowTab];
}
};
_tabViewController.didSelectTabHandler = ^void(NSTabViewItem *item) {
if([item.viewController respondsToSelector:@selector(didShowTab)]) {
[(id<MPPreferencesTab>)item.viewController didShowTab];
}
};
[self _setupDefaultPreferencesTabs];
tb.delegate = self;
self.window.toolbar = tb;
}
return self;
}
- (void)showPreferences {
if(self.defaultToolbarItems.count > 0) {
[self _showPreferencesTabWithIdentifier:self.defaultToolbarItems[0]];
}
[self showPreferencesTab:MPPreferencesTabGeneral];
}
- (void)_showPreferencesTabWithIdentifier:(NSString *)identifier {
if(nil == identifier) {
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Identifier cannot be nil" userInfo:nil];
}
id<MPPreferencesTab> tab = self.preferencesController[identifier];
if(tab == nil){
NSLog(@"Warning. Unknown settingscontroller for identifier: %@. Did you miss to add the controller?", identifier);
return;
NSInteger index = [self.tabViewController.tabView indexOfTabViewItemWithIdentifier:identifier];
/* fall back to first index if requested identifier is not know */
if(index == NSNotFound) {
index = 0;
}
self.window.toolbar.selectedItemIdentifier = identifier;
if([tab respondsToSelector:@selector(label)]) {
self.window.title = [tab label];
NSTabViewItem *item = self.tabViewController.tabViewItems[index];
if(item.label.length > 0) {
self.window.title = item.label;
}
else {
self.window.title = [tab identifier];
self.window.title = item.identifier;
}
/* Access the view before calling the willShoTab to make sure the view is fully loaded */
NSView *tabView = [(NSViewController *)tab view];
if([tab respondsToSelector:@selector(willShowTab)]) {
[tab willShowTab];
if([item.viewController respondsToSelector:@selector(willShowTab)]) {
[(id<MPPreferencesTab>)item.viewController willShowTab];
}
NSView *contentView = self.window.contentView;
if( contentView.subviews.count == 1) {
[contentView.subviews.firstObject removeFromSuperview];
}
[contentView addSubview:tabView];
[contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[tabView]-0-|"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(tabView)]];
[contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[tabView]-0-|"
options:0
metrics:nil
views:NSDictionaryOfVariableBindings(tabView)]];
self.tabViewController.selectedTabViewItemIndex = index;
[contentView layout];
[contentView layoutSubtreeIfNeeded];
if([tab respondsToSelector:@selector(didShowTab)]) {
[tab didShowTab];
if([item.viewController respondsToSelector:@selector(didShowTab)]) {
[(id<MPPreferencesTab>)item.viewController didShowTab];
}
[self.window makeKeyAndOrderFront:nil];
}
@@ -120,6 +110,9 @@
case MPPreferencesTabPlugins:
tabClass = MPPluginPreferencesController.class;
break;
case MPPreferencesTabIntegration:
tabClass = MPIntegrationPreferencesController.class;
break;
case MPPreferencesTabUpdate:
tabClass = MPUpdatePreferencesController.class;
break;
@@ -132,98 +125,41 @@
break;
}
NSString *identifier;
for(id<MPPreferencesTab> tab in self.preferencesController.allValues) {
if([tab isKindOfClass:tabClass]) {
identifier = tab.identifier;
for(NSTabViewItem *tabViewItem in self.tabViewController.tabViewItems) {
if([tabViewItem.viewController isKindOfClass:tabClass]) {
identifier = tabViewItem.identifier;
break;
}
}
[self _showPreferencesTabWithIdentifier:identifier];
}
- (void)_addSettingsTab:(id<MPPreferencesTab>)tabController {
if(NO == [tabController conformsToProtocol:@protocol(MPPreferencesTab)]) {
NSException *protocollException = [NSException exceptionWithName:NSInvalidArgumentException
reason:@"Controller must conform to MPSettingsTabProtrocoll"
userInfo:nil];
@throw protocollException;
}
if(NO == [tabController isKindOfClass:[NSViewController class]]) {
NSException *controllerException = [NSException exceptionWithName:NSInvalidArgumentException
reason:@"Controller is no NSViewController"
userInfo:nil];
@throw controllerException;
}
NSString *identifier = tabController.identifier;
if(nil != self.preferencesController[identifier]) {
NSLog(@"Warning: Settingscontroller with identifier %@ already present!", identifier);
}
else {
self.preferencesController[identifier] = tabController;
}
}
- (void)_setupDefaultPreferencesTabs {
NSArray *controllers = @[ [[MPGeneralPreferencesController alloc] init],
[[MPIntegrationPreferencesController alloc] init],
[[MPWorkflowPreferencesController alloc] init],
[[MPUpdatePreferencesController alloc] init],
[[MPPluginPreferencesController alloc] init] ];
NSMutableArray *identifier = [[NSMutableArray alloc] initWithCapacity:controllers.count];
for(id<MPPreferencesTab> controller in controllers) {
[self _addSettingsTab:controller];
[identifier addObject:controller.identifier];
}
self.defaultToolbarItems = [identifier copy];
}
- (void)_showSettingsTab:(id)sender {
if([sender respondsToSelector:@selector(itemIdentifier)]) {
NSString *identfier = [sender itemIdentifier];
[self _showPreferencesTabWithIdentifier:identfier];
NSArray<NSViewController<MPPreferencesTab>*> *controllers = @[ [[MPGeneralPreferencesController alloc] init],
[[MPIntegrationPreferencesController alloc] init],
[[MPWorkflowPreferencesController alloc] init],
[[MPUpdatePreferencesController alloc] init],
[[MPPluginPreferencesController alloc] init] ];
for(NSViewController<MPPreferencesTab> *controller in controllers) {
NSString *identifier = controller.identifier;
if([self.tabViewController tabViewItemForViewController:controller]) {
NSLog(@"Skipping adding tabViewController %@ since it's already been added before", controller);
continue;
}
if(NSNotFound != [self.tabViewController.tabView indexOfTabViewItemWithIdentifier:identifier]) {
NSLog(@"Warning: Duplicate identifiers %@ used for different tabs. Skipping adding %@ since the identifier is not unique", identifier, controller);
}
NSTabViewItem *item = [NSTabViewItem tabViewItemWithViewController:controller];
item.identifier = controller.identifier;
if([controller respondsToSelector:@selector(label)]) {
item.label = controller.label;
}
if([controller respondsToSelector:@selector(image)]) {
item.image = controller.image;
}
[self.tabViewController addTabViewItem:item];
}
}
#pragma mark NSToolbarDelegate
- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar *)toolbar {
return self.preferencesController.allKeys;
}
- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar *)toolbar {
return self.defaultToolbarItems;
}
- (NSArray *)toolbarSelectableItemIdentifiers:(NSToolbar *)toolbar {
return self.preferencesController.allKeys;
}
- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag {
NSToolbarItem *item = self.toolbarItems[itemIdentifier];
if(nil == item) {
item = [[NSToolbarItem alloc] initWithItemIdentifier:itemIdentifier];
/*
Setup the item to use the controllers label if one is present
and supports the appropriate @optional protocol messages
*/
id<MPPreferencesTab> tab = self.preferencesController[itemIdentifier];
if([tab respondsToSelector:@selector(label)]) {
item.label = [tab label];
}
else {
item.label = itemIdentifier;
}
if([tab respondsToSelector:@selector(image)]) {
item.image = [tab image];
}
else {
item.image = [NSImage imageNamed:NSImageNameCaution];
}
item.action = @selector(_showSettingsTab:);
self.toolbarItems[itemIdentifier] = item;
}
return item;
}
@end

View File

@@ -41,6 +41,16 @@ NSString *const MPPrettyPasswordTransformerName = @"com.hicknhack.macpass.MPPret
forName:MPPrettyPasswordTransformerName];
}
- (id)reverseTransformedValue:(id)value {
if([value isKindOfClass:NSString.class]) {
return value;
}
if([value isKindOfClass:NSAttributedString.class]) {
return ((NSAttributedString *)value).string;
}
return nil;
}
- (id)transformedValue:(id)value {
if([value isKindOfClass:NSString.class]) {
return ((NSString *)value).passwordPrettified;

View File

@@ -22,6 +22,10 @@
#import <Cocoa/Cocoa.h>
/* TouchID */
APPKIT_EXTERN NSString *const kMPSettingsKeyEntryTouchIdEnabled;
APPKIT_EXTERN NSString *const kMPSettingsKeyEntryTouchIdDatabaseEncryptedKeyFormat;
/* Clipboard */
APPKIT_EXTERN NSString *const kMPSettingsKeyPasteboardClearTimeout;
APPKIT_EXTERN NSString *const kMPSettingsKeyClearPasteboardOnQuit;
@@ -61,15 +65,15 @@ APPKIT_EXTERN NSString *const kMPSettingsKeyRememeberdKeysForDatabases; //
APPKIT_EXTERN NSString *const kMPSettingsKeyRememberKeyFilesForDatabases; // YES if key files should be remembers
/* Autotype */
APPKIT_EXTERN NSString *const kMPSettingsKeySendCommandForControlKey; // Should MacPass swap control for command. This is useful in a cross platform environment
APPKIT_EXTERN NSString *const kMPSettingsKeyEnableGlobalAutotype; // Is Global Autotype enabled?
APPKIT_EXTERN NSString *const kMPSettingsKeyGlobalAutotypeKeyDataKey; // The stored Data for the user defined global autotype key
APPKIT_EXTERN NSString *const kMPSettingsKeyDefaultGlobalAutotypeSequence; // Default sequence used for Autotype
APPKIT_EXTERN NSString *const kMPSettingsKeyAutotypeMatchTitle; // Autotype lookup includes entry title
APPKIT_EXTERN NSString *const kMPSettingsKeyAutotypeMatchURL; // Autotype lookup includes entry URL
APPKIT_EXTERN NSString *const kMPSettingsKeyAutotypeMatchHost; // Autotype lookup includes host part of entry URL
APPKIT_EXTERN NSString *const kMPSettingsKeyAutotypeMatchTags; // Autotype lookup includes tags for entries
APPKIT_EXTERN NSString *const kMPSettingsKeyAutotpyeHideMissingPermissionsWarning;
APPKIT_EXTERN NSString *const kMPSettingsKeySendCommandForControlKey; // Should MacPass swap control for command. This is useful in a cross platform environment
APPKIT_EXTERN NSString *const kMPSettingsKeyEnableGlobalAutotype; // Is Global Autotype enabled?
APPKIT_EXTERN NSString *const kMPSettingsKeyGlobalAutotypeKeyDataKey; // The stored Data for the user defined global autotype key
APPKIT_EXTERN NSString *const kMPSettingsKeyDefaultGlobalAutotypeSequence; // Default sequence used for Autotype
APPKIT_EXTERN NSString *const kMPSettingsKeyAutotypeMatchTitle; // Autotype lookup includes entry title
APPKIT_EXTERN NSString *const kMPSettingsKeyAutotypeMatchURL; // Autotype lookup includes entry URL
APPKIT_EXTERN NSString *const kMPSettingsKeyAutotypeMatchHost; // Autotype lookup includes host part of entry URL
APPKIT_EXTERN NSString *const kMPSettingsKeyAutotypeMatchTags; // Autotype lookup includes tags for entries
APPKIT_EXTERN NSString *const kMPSettingsKeyGloablAutotypeAlwaysShowCandidateSelection; // If YES, will always display then candidate selection window befor perfoming an Autotype
/* Search */
APPKIT_EXTERN NSString *const kMPSettingsKeyEntrySearchFilterContext;
@@ -81,6 +85,7 @@ APPKIT_EXTERN NSString *const kMPSettingsKeyEnableQuicklookPreview;
APPKIT_EXTERN NSString *const kMPSettingsKeyDoubleClickURLAction;
APPKIT_EXTERN NSString *const kMPSettingsKeyDoubleClickTitleAction;
APPKIT_EXTERN NSString *const kMPSettingsKeyUpdatePasswordOnTemplateEntries;
APPKIT_EXTERN NSString *const kMPSettingsKeyGeneratePasswordForNewEntires;
APPKIT_EXTERN NSString *const kMPSettingsKeyHideAfterCopyToClipboard;
/* Plugins */
@@ -89,13 +94,15 @@ APPKIT_EXTERN NSString *const kMPSettingsKeyDisabledPlugins; // N
APPKIT_EXTERN NSString *const kMPSettingsKeyLoadIncompatiblePlugins; // If set to YES incompatible plugins (no version info, marked as incompatible, etc) will be loaded regardless
APPKIT_EXTERN NSString *const kMPSettingsKeyHideIncopatiblePluginsWarning; // Do not show an alert, when MacPass encounteres incompatible plugins
APPKIT_EXTERN NSString *const kMPSettingsKeyAllowRemoteFetchOfPluginRepository; // Allow the download of the plugin repository file
APPKIT_EXTERN NSString *const kMPSettingsKeyPluginHideAksForRemoveConnectionPermission;
/* Network */
APPKIT_EXTERN NSString *const kMPSettingsKeyFaviconDownloadMethod;
typedef NS_ENUM(NSUInteger, MPFileChangeStrategy) {
MPFileChangeStrategyAsk,
MPFileChangeStrategyKeepMine,
MPFileChangeStrategyUseOther,
MPFileChangeStrategyMerge
MPFileChangeStrategyMerge,
};
typedef NS_ENUM(NSUInteger, MPDoubleClickURLAction) {
@@ -108,6 +115,12 @@ typedef NS_ENUM(NSUInteger, MPDoubleClickTitleAction) {
MPDoubleClickTitleActionIgnore,
};
typedef NS_ENUM(NSUInteger, MPFaviconDownloadMethod) {
MPFaviconDownloadMethodDirect,
MPFaviconDownloadMethodDuckDuckGo,
MPFaviconDownloadMethodGoogle,
};
/* Password Generation */
APPKIT_EXTERN NSString *const kMPSettingsKeyCopyGeneratedPasswordToClipboard;
APPKIT_EXTERN NSString *const kMPSettingsKeyDefaultPasswordLength;

View File

@@ -26,66 +26,72 @@
#import "MPEntrySearchContext.h"
#import "DDHotKey+MacPassAdditions.h" // Default hotkey;
NSString *const kMPSettingsKeyPasteboardClearTimeout = @"ClipboardClearTimeout";
NSString *const kMPSettingsKeyClearPasteboardOnQuit = @"ClearClipboardOnQuit";
NSString *const kMPSettingsKeyPreventUniversalClipboard = @"PreventUniversalClipboard";
NSString *const kMPSettingsKeyBrowserBundleId = @"BrowserBundleId";
NSString *const kMPSettingsKeyOpenEmptyDatabaseOnLaunch = @"OpenEmptyDatabaseOnLaunch";
NSString *const kMPSettingsKeyReopenLastDatabaseOnLaunch = @"ReopenLastDatabaseOnLaunch";
NSString *const kMPSettingsKeyQuitOnLastWindowClose = @"QuitOnLastWindowClose";
NSString *const kMPSettingsKeyFileChangeStrategy = @"FileChangeStrategy";
NSString *const kMPSettingsKeyEnableAutosave = @"EnableAutosave";
NSString *const kMPSettingsKeyLockOnSleep = @"LockOnSleep";
NSString *const kMPSettingskeyLockOnLogout = @"LockOnLogout";
NSString *const kMPSettingskeyLockOnScreenSleep = @"LockOnScreenSleep";
NSString *const kMPSettingsKeyIdleLockTimeOut = @"IdleLockTimeOut";
NSString *const kMPSettingsKeyShowInspector = @"ShowInspector";
NSString *const kMPSettingsKeyEntryTableSortDescriptors = @"EntryTableSortDescriptors";
NSString *const kMPSettingsKeyPasteboardClearTimeout = @"ClipboardClearTimeout";
NSString *const kMPSettingsKeyClearPasteboardOnQuit = @"ClearClipboardOnQuit";
NSString *const kMPSettingsKeyPreventUniversalClipboard = @"PreventUniversalClipboard";
NSString *const kMPSettingsKeyBrowserBundleId = @"BrowserBundleId";
NSString *const kMPSettingsKeyOpenEmptyDatabaseOnLaunch = @"OpenEmptyDatabaseOnLaunch";
NSString *const kMPSettingsKeyReopenLastDatabaseOnLaunch = @"ReopenLastDatabaseOnLaunch";
NSString *const kMPSettingsKeyQuitOnLastWindowClose = @"QuitOnLastWindowClose";
NSString *const kMPSettingsKeyFileChangeStrategy = @"FileChangeStrategy";
NSString *const kMPSettingsKeyEnableAutosave = @"EnableAutosave";
NSString *const kMPSettingsKeyLockOnSleep = @"LockOnSleep";
NSString *const kMPSettingskeyLockOnLogout = @"LockOnLogout";
NSString *const kMPSettingskeyLockOnScreenSleep = @"LockOnScreenSleep";
NSString *const kMPSettingsKeyIdleLockTimeOut = @"IdleLockTimeOut";
NSString *const kMPSettingsKeyShowInspector = @"ShowInspector";
NSString *const kMPSettingsKeyEntryTableSortDescriptors = @"EntryTableSortDescriptors";
NSString *const kMPSettingsKeyLegacyHideTitle = @"LegacyHideTitle";
NSString *const kMPSettingsKeyLegacyHideUsername = @"LegacyHideUsername ";
NSString *const kMPSettingsKeyLegacyHidePassword = @"LegacyHidePassword";
NSString *const kMPSettingsKeyLegacyHideNotes = @"LegacyHideNotes";
NSString *const kMPSettingsKeyLegacyHideURL = @"LegacyHideURL";
NSString *const kMPSettingsKeyLegacyHideTitle = @"LegacyHideTitle";
NSString *const kMPSettingsKeyLegacyHideUsername = @"LegacyHideUsername ";
NSString *const kMPSettingsKeyLegacyHidePassword = @"LegacyHidePassword";
NSString *const kMPSettingsKeyLegacyHideNotes = @"LegacyHideNotes";
NSString *const kMPSettingsKeyLegacyHideURL = @"LegacyHideURL";
NSString *const kMPSettingsKeyLastDatabasePath = @"LastDatabasePath";
NSString *const kMPSettingsKeyRememberKeyFilesForDatabases = @"RememberKeyFilesForDatabases";
NSString *const kMPSettingsKeyRememeberdKeysForDatabases = @"RememeberdKeysForDatabases";
NSString *const kMPSettingsKeyLastDatabasePath = @"LastDatabasePath";
NSString *const kMPSettingsKeyRememberKeyFilesForDatabases = @"RememberKeyFilesForDatabases";
NSString *const kMPSettingsKeyRememeberdKeysForDatabases = @"RememeberdKeysForDatabases";
NSString *const kMPSettingsKeySendCommandForControlKey = @"SendCommandKeyForControlKey";
NSString *const kMPSettingsKeyEnableGlobalAutotype = @"EnableGlobalAutotype";
NSString *const kMPSettingsKeyGlobalAutotypeKeyDataKey = @"GlobalAutotypeKeyDataKey";
NSString *const kMPSettingsKeyDefaultGlobalAutotypeSequence = @"DefaultGlobalAutotypeSequence";
NSString *const kMPSettingsKeyAutotypeMatchTitle = @"AutotypeMatchTitle";
NSString *const kMPSettingsKeyAutotypeMatchURL = @"AutotypeMatchURL";
NSString *const kMPSettingsKeyAutotypeMatchHost = @"AutotypeMatchHost";
NSString *const kMPSettingsKeyAutotypeMatchTags = @"AutotypeMatchTags";
NSString *const kMPSettingsKeyAutotpyeHideMissingPermissionsWarning = @"AutotpyeHideMissingPermissionsWarning";
NSString *const kMPSettingsKeySendCommandForControlKey = @"SendCommandKeyForControlKey";
NSString *const kMPSettingsKeyEnableGlobalAutotype = @"EnableGlobalAutotype";
NSString *const kMPSettingsKeyGlobalAutotypeKeyDataKey = @"GlobalAutotypeKeyDataKey";
NSString *const kMPSettingsKeyDefaultGlobalAutotypeSequence = @"DefaultGlobalAutotypeSequence";
NSString *const kMPSettingsKeyAutotypeMatchTitle = @"AutotypeMatchTitle";
NSString *const kMPSettingsKeyAutotypeMatchURL = @"AutotypeMatchURL";
NSString *const kMPSettingsKeyAutotypeMatchHost = @"AutotypeMatchHost";
NSString *const kMPSettingsKeyAutotypeMatchTags = @"AutotypeMatchTags";
NSString *const kMPSettingsKeyGloablAutotypeAlwaysShowCandidateSelection = @"GloablAutotypeAlwaysShowCandidateSelection";
NSString *const kMPSettingsKeyEntrySearchFilterContext = @"EntrySearchFilterContext";
NSString *const kMPSettingsKeyEntryTouchIdEnabled = @"EnableSubsequentUnlocksWithTouchID";
NSString *const kMPSettingsKeyEntryTouchIdDatabaseEncryptedKeyFormat = @"EncryptedDatabaseKeyForTouchID-%@";
NSString *const kMPSettingsKeyEnableQuicklookPreview = @"EnableQuicklookPreview";
NSString *const kMPSettingsKeyEntrySearchFilterContext = @"EntrySearchFilterContext";
NSString *const kMPSettingsKeyCopyGeneratedPasswordToClipboard = @"CopyGeneratedPasswordToClipboard";
NSString *const kMPSettingsKeyEnableQuicklookPreview = @"EnableQuicklookPreview";
NSString *const kMPSettingsKeyDefaultPasswordLength = @"DefaultPasswordLength";
NSString *const kMPSettingsKeyPasswordCharacterFlags = @"PasswordCharacterFlags";
NSString *const kMPSettingsKeyPasswordEnsureOccurance = @"PasswordEnsureOccurance";
NSString *const kMPSettingsKeyPasswordUseCustomString = @"PasswordUseCustomString";
NSString *const kMPSettingsKeyPasswordCustomString = @"PasswordCustomString";
NSString *const kMPSettingsKeyCopyGeneratedPasswordToClipboard = @"CopyGeneratedPasswordToClipboard";
NSString *const kMPSettingsKeyPasswordDefaultsForEntry = @"PasswordDefaultsForEntry";
NSString *const kMPSettingsKeyDefaultPasswordLength = @"DefaultPasswordLength";
NSString *const kMPSettingsKeyPasswordCharacterFlags = @"PasswordCharacterFlags";
NSString *const kMPSettingsKeyPasswordEnsureOccurance = @"PasswordEnsureOccurance";
NSString *const kMPSettingsKeyPasswordUseCustomString = @"PasswordUseCustomString";
NSString *const kMPSettingsKeyPasswordCustomString = @"PasswordCustomString";
NSString *const kMPSettingsKeyDoubleClickURLAction = @"DoubleClickURLAction";
NSString *const kMPSettingsKeyDoubleClickTitleAction = @"DoubleClickTitleAction";
NSString *const kMPSettingsKeyUpdatePasswordOnTemplateEntries = @"UpdatePasswordOnTemplateEntries";
NSString *const kMPSettingsKeyHideAfterCopyToClipboard = @"HideAfterCopyToClipboard";
NSString *const kMPSettingsKeyPasswordDefaultsForEntry = @"PasswordDefaultsForEntry";
NSString *const kMPSettingsKeyLoadUnsecurePlugins = @"LoadUnsecurePlugins";
NSString *const kMPSettingsKeyLoadIncompatiblePlugins = @"LoadIncompatiblePlugins";
NSString *const kMPSettingsKeyDisabledPlugins = @"DisabledPlugins";
NSString *const kMPSettingsKeyHideIncopatiblePluginsWarning = @"HideIncopatiblePluginsWarning";
NSString *const kMPSettingsKeyAllowRemoteFetchOfPluginRepository = @"AllowRemoteFetchOfPluginRepository";
NSString *const kMPSettingsKeyDoubleClickURLAction = @"DoubleClickURLAction";
NSString *const kMPSettingsKeyDoubleClickTitleAction = @"DoubleClickTitleAction";
NSString *const kMPSettingsKeyUpdatePasswordOnTemplateEntries = @"UpdatePasswordOnTemplateEntries";
NSString *const kMPSettingsKeyGeneratePasswordForNewEntires = @"GeneratePasswordForNewEntires";
NSString *const kMPSettingsKeyHideAfterCopyToClipboard = @"HideAfterCopyToClipboard";
NSString *const kMPSettingsKeyLoadUnsecurePlugins = @"LoadUnsecurePlugins";
NSString *const kMPSettingsKeyLoadIncompatiblePlugins = @"LoadIncompatiblePlugins";
NSString *const kMPSettingsKeyDisabledPlugins = @"DisabledPlugins";
NSString *const kMPSettingsKeyHideIncopatiblePluginsWarning = @"HideIncopatiblePluginsWarning";
NSString *const kMPSettingsKeyAllowRemoteFetchOfPluginRepository = @"AllowRemoteFetchOfPluginRepository";
NSString *const kMPSettingsKeyFaviconDownloadMethod = @"FaviconDownloadMethod";
/* Deprecated */
NSString *const kMPDeprecatedSettingsKeyRememberKeyFilesForDatabases = @"kMPSettingsKeyRememberKeyFilesForDatabases";
@@ -160,11 +166,14 @@ NSString *const kMPDepricatedSettingsKeyAutotypeHideAccessibiltyWarning = @"Au
kMPSettingsKeyDoubleClickTitleAction: @(MPDoubleClickTitleActionInspect),
kMPSettingsKeyLoadUnsecurePlugins: @NO,
kMPSettingsKeyUpdatePasswordOnTemplateEntries: @YES,
kMPSettingsKeyGeneratePasswordForNewEntires: @YES,
kMPSettingsKeyDisabledPlugins: @[],
kMPSettingsKeyLoadIncompatiblePlugins: @NO,
kMPSettingsKeyQuitOnLastWindowClose: @NO,
kMPSettingsKeyEnableAutosave: @YES,
kMPSettingsKeyHideAfterCopyToClipboard: @NO
kMPSettingsKeyHideAfterCopyToClipboard: @NO,
kMPSettingsKeyFaviconDownloadMethod: @(MPFaviconDownloadMethodDirect), // Download directly from host
kMPSettingsKeyGloablAutotypeAlwaysShowCandidateSelection: @NO
};
});
return standardDefaults;
@@ -212,7 +221,7 @@ NSString *const kMPDepricatedSettingsKeyAutotypeHideAccessibiltyWarning = @"Au
if(!descriptorData) {
return; // No user defaults
}
NSArray *sortDescriptors = [NSUnarchiver unarchiveObjectWithData:descriptorData];
NSArray *sortDescriptors = [NSKeyedUnarchiver unarchiveObjectWithData:descriptorData];
for(NSSortDescriptor *descriptor in sortDescriptors) {
/* Brute force, just kill the settings if they might cause trouble */

View File

@@ -0,0 +1,17 @@
//
// MPTOTPSetupViewController.h
// MacPass
//
// Created by Michael Starke on 10.12.20.
// Copyright © 2020 HicknHack Software GmbH. All rights reserved.
//
#import <Cocoa/Cocoa.h>
NS_ASSUME_NONNULL_BEGIN
@interface MPTOTPSetupViewController : NSViewController
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,144 @@
//
// MPTOTPSetupViewController.m
// MacPass
//
// Created by Michael Starke on 10.12.20.
// Copyright © 2020 HicknHack Software GmbH. All rights reserved.
//
#import "MPTOTPSetupViewController.h"
#import "NSImage+MPQRCode.h"
#import <KeePassKit/KeePassKit.h>
@interface MPTOTPSetupViewController ()
@property (strong) IBOutlet NSTextField *urlTextField;
@property (strong) IBOutlet NSTextField *secretTextField;
@property (strong) IBOutlet NSPopUpButton *algorithmPopUpButton;
@property (strong) IBOutlet NSTextField *timeStepTextField;
@property (strong) IBOutlet NSStepper *timeStepStepper;
@property (strong) IBOutlet NSPopUpButton *digitCountPopUpButton;
@property (strong) IBOutlet NSImageView *qrCodeImageView;
@property (strong) IBOutlet NSGridView *gridView;
@property (strong) IBOutlet NSPopUpButton *typePopUpButton;
@property (strong) KPKTimeOTPGenerator *generator;
@property NSInteger timeSlice;
@end
typedef NS_ENUM(NSUInteger, MPOTPUpdateSource) {
MPOTPUpdateSourceQRImage,
MPOTPUpdateSourceURL,
MPOTPUpdateSourceSecret,
MPOTPUpdateSourceAlgorithm,
MPOTPUpdateSourceTimeSlice,
MPOTPUpdateSourceEntry
};
typedef NS_ENUM(NSUInteger, MPOTPType) {
MPOTPTypeRFC,
MPOTPTypeSteam,
MPOTPTypeCustom
};
@implementation MPTOTPSetupViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSAssert([self.representedObject isKindOfClass:KPKEntry.class], @"represented object needs to be a KPKEntry");
/* algorithm */
NSMenuItem *sha1Item = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"HASH_SHA1", "SHA 1 hash algoritm menu item") action:NULL keyEquivalent:@""];
sha1Item.tag = KPKOTPHashAlgorithmSha1;
NSMenuItem *sha256Item = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"HASH_SHA256", "SHA 256 hash algoritm menu item") action:NULL keyEquivalent:@""];
sha256Item.tag = KPKOTPHashAlgorithmSha256;
NSMenuItem *sha512Item = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"HASH_SHA512", "SHA 512 hash algoritm menu item") action:NULL keyEquivalent:@""];
sha512Item.tag = KPKOTPHashAlgorithmSha512;
NSAssert(self.algorithmPopUpButton.menu.numberOfItems == 0, @"Hash algorithm menu needs to be empty");
[self.algorithmPopUpButton.menu addItem:sha1Item];
[self.algorithmPopUpButton.menu addItem:sha256Item];
[self.algorithmPopUpButton.menu addItem:sha512Item];
/* digits */
NSAssert(self.digitCountPopUpButton.menu.numberOfItems == 0, @"Digit menu needs to be empty");
for(NSUInteger digit = 6; digit <= 8; digit++) {
NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:[NSString stringWithFormat:@"%ld", digit] action:NULL keyEquivalent:@""];
item.tag = digit;
[self.digitCountPopUpButton.menu addItem:item];
}
NSAssert(self.typePopUpButton.menu.numberOfItems == 0, @"Type menu needs to be empty!");
NSMenuItem *rfcItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"OTP_RFC", @"OTP type RFC ") action:NULL keyEquivalent:@""];
rfcItem.tag = MPOTPTypeRFC;
NSMenuItem *steamItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"OTP_STEAM", @"OTP type Steam ") action:NULL keyEquivalent:@""];
steamItem.tag = MPOTPTypeSteam;
NSMenuItem *customItem = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"OTP_CUSTOM", @"OTP custom type ") action:NULL keyEquivalent:@""];
customItem.tag = MPOTPTypeCustom;
[self.typePopUpButton.menu addItem:rfcItem];
[self.typePopUpButton.menu addItem:steamItem];
[self.typePopUpButton.menu addItem:customItem];
[self.timeStepTextField bind:NSValueBinding toObject:self withKeyPath:NSStringFromSelector(@selector(timeSlice)) options:nil];
[self.timeStepStepper bind:NSValueBinding toObject:self withKeyPath:NSStringFromSelector(@selector(timeSlice)) options:nil];
[self _updateView:MPOTPUpdateSourceEntry];
}
- (IBAction)toggleDisclosure:(id)sender {
for(NSInteger row = 1; row < self.gridView.numberOfRows; row++) {
NSGridRow *gridRow = [self.gridView rowAtIndex:row];
gridRow.hidden = !gridRow.hidden;
}
}
- (IBAction)parseQRCode:(id)sender {
if(sender != self.qrCodeImageView) {
return; // wrong sender
}
[self _updateView:MPOTPUpdateSourceQRImage];
}
- (void)_updateView:(MPOTPUpdateSource)source {
self.generator = [[KPKTimeOTPGenerator alloc] initWithAttributes:((KPKEntry *)self.representedObject).attributes];
if(source == MPOTPUpdateSourceQRImage) {
NSString *qrCodeString = self.qrCodeImageView.image.QRCodeString;
NSURL *otpURL = [NSURL URLWithString:qrCodeString];
if(!otpURL.isTimeOTPURL) {
return; // no valid URL
}
self.urlTextField.stringValue = otpURL.absoluteString;
}
/* FIXME: update correct values based on changes */
/* URL and QR code */
KPKEntry *entry = self.representedObject;
NSString *url = [entry attributeWithKey:kKPKAttributeKeyOTPOAuthURL].value;
self.urlTextField.stringValue = @"";
if(url) {
NSURL *authURL = [NSURL URLWithString:url];
if(authURL.isTimeOTPURL) {
self.urlTextField.stringValue = authURL.absoluteString;
self.qrCodeImageView.image = [NSImage QRCodeImageWithString:authURL.absoluteString];
}
}
/* secret */
NSString *secret = [self.generator.key base32EncodedString];
self.secretTextField.stringValue = secret ? secret : @"";
[self.algorithmPopUpButton selectItemWithTag:self.generator.hashAlgorithm];
[self.digitCountPopUpButton selectItemWithTag:self.generator.numberOfDigits];
self.timeSlice = self.generator.timeSlice;
}
@end

View File

@@ -0,0 +1,220 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment version="101304" identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17701"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="MPTOTPSetupViewController">
<connections>
<outlet property="algorithmPopUpButton" destination="caF-Au-ey8" id="aZJ-ee-acD"/>
<outlet property="digitCountPopUpButton" destination="aa3-XV-Chc" id="Ghc-Mp-R8f"/>
<outlet property="gridView" destination="4gl-4p-0WY" id="hvW-TB-Elg"/>
<outlet property="qrCodeImageView" destination="yS5-M0-RSB" id="s9E-ID-WQz"/>
<outlet property="secretTextField" destination="Bt8-9X-91R" id="mtn-nj-3oO"/>
<outlet property="timeStepStepper" destination="CgJ-Qt-NPu" id="JxC-E8-BXY"/>
<outlet property="timeStepTextField" destination="AdN-zI-C65" id="ebN-x3-AIN"/>
<outlet property="typePopUpButton" destination="ku7-YD-kkV" id="8zT-Y5-6Wa"/>
<outlet property="urlTextField" destination="GJN-85-eYH" id="Y1F-zI-hLu"/>
<outlet property="view" destination="Hz6-mo-xeY" id="0bl-1N-x8E"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customView id="Hz6-mo-xeY">
<rect key="frame" x="0.0" y="0.0" width="354" height="301"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<gridView xPlacement="leading" yPlacement="center" rowAlignment="firstBaseline" rowSpacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="4gl-4p-0WY">
<rect key="frame" x="20" y="28" width="314" height="253"/>
<constraints>
<constraint firstItem="GJN-85-eYH" firstAttribute="trailing" secondItem="Bt8-9X-91R" secondAttribute="trailing" id="9fv-9s-YwU"/>
<constraint firstItem="AdN-zI-C65" firstAttribute="trailing" secondItem="Bt8-9X-91R" secondAttribute="trailing" id="xXQ-D9-G21"/>
</constraints>
<rows>
<gridRow yPlacement="center" topPadding="4" bottomPadding="4" id="T2o-We-WjN"/>
<gridRow yPlacement="fill" id="leK-j9-Cah"/>
<gridRow yPlacement="none" id="J7I-Uw-OQv"/>
<gridRow yPlacement="none" id="GmF-7D-t30"/>
<gridRow id="hS6-e9-JPg"/>
<gridRow id="QY3-TF-Rbs"/>
<gridRow id="0Jy-aF-Wst"/>
</rows>
<columns>
<gridColumn xPlacement="trailing" id="Ar1-qh-iHT"/>
<gridColumn id="Ecc-pj-MX9"/>
<gridColumn id="aZO-dP-SsW"/>
</columns>
<gridCells>
<gridCell row="T2o-We-WjN" column="Ar1-qh-iHT" rowAlignment="lastBaseline" id="19c-m3-M2s">
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="hh3-nA-yHV">
<rect key="frame" x="46" y="209" width="59" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" title="QR Code" id="PuA-kW-t29">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</gridCell>
<gridCell row="T2o-We-WjN" column="Ecc-pj-MX9" rowAlignment="none" id="jgf-mM-CW2">
<imageView key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="yS5-M0-RSB">
<rect key="frame" x="106" y="182" width="70" height="70"/>
<constraints>
<constraint firstAttribute="width" constant="64" id="MhV-Ye-bQt"/>
<constraint firstAttribute="height" constant="64" id="RRz-CV-k1H"/>
</constraints>
<imageCell key="cell" selectable="YES" editable="YES" alignment="left" imageScaling="proportionallyDown" imageFrameStyle="grayBezel" id="BXB-xr-hqw"/>
<connections>
<action selector="parseQRCode:" target="-2" id="5u9-xL-Haj"/>
</connections>
</imageView>
</gridCell>
<gridCell row="T2o-We-WjN" column="aZO-dP-SsW" xPlacement="leading" id="0bn-HV-7V1"/>
<gridCell row="leK-j9-Cah" column="Ar1-qh-iHT" id="fgi-y3-z17">
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="e3u-QK-K24">
<rect key="frame" x="61" y="154" width="44" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" title="Secret" id="ufY-IN-5UY">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</gridCell>
<gridCell row="leK-j9-Cah" column="Ecc-pj-MX9" headOfMergedCell="q9e-Zx-LIY" yPlacement="center" id="q9e-Zx-LIY">
<textField key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Bt8-9X-91R">
<rect key="frame" x="109" y="152" width="150" height="21"/>
<constraints>
<constraint firstAttribute="width" constant="150" id="aN6-yG-12x"/>
</constraints>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" id="N3a-bO-6va">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</gridCell>
<gridCell row="leK-j9-Cah" column="aZO-dP-SsW" headOfMergedCell="q9e-Zx-LIY" id="gOO-ed-C7I"/>
<gridCell row="J7I-Uw-OQv" column="Ar1-qh-iHT" id="LYj-ea-Ou9">
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="W8L-ah-Kdc">
<rect key="frame" x="71" y="127" width="34" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" title="Type" id="fNC-fH-sYi">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</gridCell>
<gridCell row="J7I-Uw-OQv" column="Ecc-pj-MX9" headOfMergedCell="fOz-RA-6LG" id="fOz-RA-6LG">
<popUpButton key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ku7-YD-kkV">
<rect key="frame" x="107" y="120" width="38" height="25"/>
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="WbA-Ie-Txj">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="menu"/>
<menu key="menu" id="ger-Fr-8BF"/>
</popUpButtonCell>
</popUpButton>
</gridCell>
<gridCell row="J7I-Uw-OQv" column="aZO-dP-SsW" headOfMergedCell="fOz-RA-6LG" id="mka-sc-dDD"/>
<gridCell row="GmF-7D-t30" column="Ar1-qh-iHT" id="Isd-CW-srQ">
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="4Ic-Nt-YlL">
<rect key="frame" x="75" y="96" width="30" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" title="URL" id="Kci-xp-mLu">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</gridCell>
<gridCell row="GmF-7D-t30" column="Ecc-pj-MX9" headOfMergedCell="Fpx-eQ-WAY" id="Fpx-eQ-WAY">
<textField key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="GJN-85-eYH">
<rect key="frame" x="109" y="94" width="150" height="21"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" id="ZpH-Ks-BBi">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</gridCell>
<gridCell row="GmF-7D-t30" column="aZO-dP-SsW" headOfMergedCell="Fpx-eQ-WAY" id="ZXy-HZ-O3a"/>
<gridCell row="hS6-e9-JPg" column="Ar1-qh-iHT" id="5hJ-4K-a2d">
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="yiW-Wk-6YB">
<rect key="frame" x="7" y="66" width="98" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" title="Hash Algorithm" id="g3s-fk-k9Q">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</gridCell>
<gridCell row="hS6-e9-JPg" column="Ecc-pj-MX9" id="6MO-n5-2Cu">
<popUpButton key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="caF-Au-ey8">
<rect key="frame" x="107" y="59" width="38" height="25"/>
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="Rxs-11-LRy">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="menu"/>
<menu key="menu" id="zev-8W-Uhl"/>
</popUpButtonCell>
</popUpButton>
</gridCell>
<gridCell row="hS6-e9-JPg" column="aZO-dP-SsW" id="56r-vv-PhT"/>
<gridCell row="QY3-TF-Rbs" column="Ar1-qh-iHT" id="jL5-XH-KYZ">
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="JOR-bN-ZYC">
<rect key="frame" x="41" y="35" width="64" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" title="Time step" id="hbT-mm-dIn">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</gridCell>
<gridCell row="QY3-TF-Rbs" column="Ecc-pj-MX9" xPlacement="fill" id="bvB-9m-g1U">
<textField key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="AdN-zI-C65">
<rect key="frame" x="109" y="33" width="150" height="21"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" id="bHO-kq-GUf">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</gridCell>
<gridCell row="QY3-TF-Rbs" column="aZO-dP-SsW" rowAlignment="none" id="oRW-3a-WxP">
<stepper key="contentView" horizontalHuggingPriority="750" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="CgJ-Qt-NPu">
<rect key="frame" x="262" y="29" width="19" height="28"/>
<stepperCell key="cell" continuous="YES" alignment="left" maxValue="100" id="RPy-q9-wKy"/>
</stepper>
</gridCell>
<gridCell row="0Jy-aF-Wst" column="Ar1-qh-iHT" id="hWa-nU-LpX">
<textField key="contentView" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="z5V-Af-Kpa">
<rect key="frame" x="-2" y="4" width="107" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" title="Number of Digits" id="iYF-F5-nMb">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</gridCell>
<gridCell row="0Jy-aF-Wst" column="Ecc-pj-MX9" id="gil-83-ris">
<popUpButton key="contentView" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="aa3-XV-Chc">
<rect key="frame" x="107" y="-3" width="38" height="25"/>
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="rzY-5S-dIJ">
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="menu"/>
<menu key="menu" id="XCv-uH-EcW"/>
</popUpButtonCell>
</popUpButton>
</gridCell>
<gridCell row="0Jy-aF-Wst" column="aZO-dP-SsW" id="V48-br-lpl"/>
</gridCells>
</gridView>
</subviews>
<constraints>
<constraint firstAttribute="trailing" secondItem="4gl-4p-0WY" secondAttribute="trailing" constant="20" symbolic="YES" id="4eg-dj-7eq"/>
<constraint firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="4gl-4p-0WY" secondAttribute="bottom" constant="20" symbolic="YES" id="6lC-F3-SvT"/>
<constraint firstItem="4gl-4p-0WY" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" constant="20" symbolic="YES" id="QNT-yn-O32"/>
<constraint firstItem="4gl-4p-0WY" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" symbolic="YES" id="g3C-GL-weQ"/>
</constraints>
<point key="canvasLocation" x="-989" y="-832"/>
</customView>
</objects>
</document>

View File

@@ -0,0 +1,21 @@
//
// MPOTPViewController.h
// MacPass
//
// Created by Michael Starke on 27.11.20.
// Copyright © 2020 HicknHack Software GmbH. All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import <HNHUi/HNHUi.h>
NS_ASSUME_NONNULL_BEGIN
@interface MPTOTPViewController : NSViewController
@property (strong) IBOutlet HNHUITextField *toptValueTextField;
@property (strong) IBOutlet NSButton *remainingTimeButton;
@property (strong) IBOutlet NSButton *showSetupButton;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,72 @@
//
// MPOTPViewController.m
// MacPass
//
// Created by Michael Starke on 27.11.20.
// Copyright © 2020 HicknHack Software GmbH. All rights reserved.
//
#import "MPTOTPViewController.h"
#import <KeePassKit/KeePassKit.h>
#import "MPEntryInspectorViewController.h"
@interface MPTOTPViewController ()
@property (strong) KPKTimeOTPGenerator *generator;
@end
@implementation MPTOTPViewController
- (void)viewDidLoad {
self.remainingTimeButton.title = @"";
}
- (IBAction)showOTPSetup:(id)sender {
MPEntryInspectorViewController *vs = (MPEntryInspectorViewController*)self.parentViewController;
[vs showOTPSetup:sender];
}
- (void)setRepresentedObject:(id)representedObject {
NSArray *notificationNames = @[KPKWillAddAttributeNotification, KPKDidAddAttributeNotification, KPKWillChangeAttributeNotification, KPKDidChangeAttributeNotification, KPKWillRemoveAttributeNotification, KPKDidRemoveAttributeNotification];
if(self.representedObject) {
for(NSString *notificationName in notificationNames) {
[NSNotificationCenter.defaultCenter removeObserver:self name:notificationName object:self.representedObject];
}
}
super.representedObject = representedObject;
if(representedObject) {
for(NSString *notificationName in notificationNames) {
[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(_didChangeAttribute:) name:notificationName object:representedObject];
}
}
[self _didChangeAttribute:nil];
}
- (void)_didChangeAttribute:(NSNotification *)notification {
[self _updateDisplay];
}
- (void)_updateDisplay {
KPKEntry *entry = (KPKEntry *)self.representedObject;
BOOL showTOTP = entry.hasTimeOTP;
self.view.hidden = !showTOTP;
if(showTOTP) {
self.generator = [[KPKTimeOTPGenerator alloc] initWithAttributes:entry.attributes];
self.generator.time = NSDate.date.timeIntervalSince1970;
NSString *stringValue = self.generator.string;
self.toptValueTextField.stringValue = stringValue ? stringValue : @"";
NSString *template = NSLocalizedString(@"TOTP_REMAINING_TIME_%ld_SECONDS", @"Time in seconds remaining for a valid TOTP string, format should be %ld");
self.remainingTimeButton.title = [NSString stringWithFormat:template, (NSUInteger)self.generator.remainingTime];
[self performSelector:@selector(_updateDisplay) withObject:nil afterDelay:0.5];
}
else {
self.remainingTimeButton.title = @"";
self.toptValueTextField.stringValue = @"";
}
}
@end

View File

@@ -0,0 +1,97 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17701"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="MPTOTPViewController">
<connections>
<outlet property="remainingTimeButton" destination="Hxg-bd-l1O" id="QJf-RB-7JY"/>
<outlet property="showSetupButton" destination="xge-Jc-QnB" id="BiU-0e-j2c"/>
<outlet property="toptValueTextField" destination="xBL-Jz-VQO" id="QwC-Um-82o"/>
<outlet property="view" destination="Hz6-mo-xeY" id="0bl-1N-x8E"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customView id="Hz6-mo-xeY">
<rect key="frame" x="0.0" y="0.0" width="480" height="43"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<stackView distribution="fill" orientation="vertical" alignment="leading" horizontalStackHuggingPriority="250" verticalStackHuggingPriority="250" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Lz5-aM-o4b">
<rect key="frame" x="0.0" y="0.0" width="480" height="43"/>
<subviews>
<textField horizontalHuggingPriority="249" verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="r8F-6m-CG6">
<rect key="frame" x="-2" y="29" width="484" height="14"/>
<textFieldCell key="cell" controlSize="small" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" title="TOTP" id="mP4-nH-7TA">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="disabledControlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<stackView distribution="fill" orientation="horizontal" alignment="firstBaseline" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="avD-My-tnu">
<rect key="frame" x="0.0" y="0.0" width="480" height="21"/>
<subviews>
<textField horizontalHuggingPriority="249" verticalHuggingPriority="750" allowsCharacterPickerTouchBarItem="YES" translatesAutoresizingMaskIntoConstraints="NO" id="xBL-Jz-VQO" customClass="HNHUITextField">
<rect key="frame" x="0.0" y="0.0" width="399" height="21"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" truncatesLastVisibleLine="YES" selectable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" drawsBackground="YES" usesSingleLineMode="YES" id="Vuy-HC-UhI">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Hxg-bd-l1O">
<rect key="frame" x="407" y="1" width="27" height="17"/>
<buttonCell key="cell" type="inline" title="30" bezelStyle="inline" alignment="center" enabled="NO" borderStyle="border" inset="2" id="roW-Uk-ff9">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="smallSystemBold"/>
</buttonCell>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="xge-Jc-QnB">
<rect key="frame" x="436" y="-7" width="50" height="32"/>
<buttonCell key="cell" type="push" bezelStyle="rounded" image="NSActionTemplate" imagePosition="only" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="64a-Tn-vdd">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="showOTPSetup:" target="-2" id="bgd-gi-zp9"/>
</connections>
</button>
</subviews>
<visibilityPriorities>
<integer value="1000"/>
<integer value="1000"/>
<integer value="1000"/>
</visibilityPriorities>
<customSpacing>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
</customSpacing>
</stackView>
</subviews>
<visibilityPriorities>
<integer value="1000"/>
<integer value="1000"/>
</visibilityPriorities>
<customSpacing>
<real value="3.4028234663852886e+38"/>
<real value="3.4028234663852886e+38"/>
</customSpacing>
</stackView>
</subviews>
<constraints>
<constraint firstAttribute="bottom" secondItem="Lz5-aM-o4b" secondAttribute="bottom" id="JFd-zk-sz4"/>
<constraint firstAttribute="trailing" secondItem="Lz5-aM-o4b" secondAttribute="trailing" id="vne-gZ-Ec8"/>
<constraint firstItem="Lz5-aM-o4b" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" id="y4i-uB-HlK"/>
<constraint firstItem="Lz5-aM-o4b" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" id="zFP-JZ-Qtu"/>
</constraints>
<point key="canvasLocation" x="-180" y="74"/>
</customView>
</objects>
<resources>
<image name="NSActionTemplate" width="14" height="14"/>
</resources>
</document>

View File

@@ -0,0 +1,20 @@
//
// MPTabViewController.h
// MacPass
//
// Created by Michael Starke on 30.06.20.
// Copyright © 2020 HicknHack Software GmbH. All rights reserved.
//
#import <Cocoa/Cocoa.h>
NS_ASSUME_NONNULL_BEGIN
@interface MPTabViewController : NSTabViewController
@property (nonatomic, copy, nullable) void (^willSelectTabHandler)(NSTabViewItem *item);
@property (nonatomic, copy, nullable) void (^didSelectTabHandler)(NSTabViewItem *item);
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,65 @@
//
// MPTabViewController.m
// MacPass
//
// Created by Michael Starke on 30.06.20.
// Copyright © 2020 HicknHack Software GmbH. All rights reserved.
//
#import "MPTabViewController.h"
@interface MPTabViewController ()
@property (strong) NSMutableDictionary<NSString *, NSValue*> *tabViewSizes;
@end
@implementation MPTabViewController
- (instancetype)initWithNibName:(NSNibName)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if(self) {
_tabViewSizes = [[NSMutableDictionary alloc] init];
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)coder {
self = [super initWithCoder:coder];
if(self) {
_tabViewSizes = [[NSMutableDictionary alloc] init];
}
return self;
}
- (void)tabView:(NSTabView *)tabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem {
[super tabView:tabView didSelectTabViewItem:tabViewItem];
[self _resizeWindowToFitTabView:tabViewItem];
if(self.didSelectTabHandler) {
self.didSelectTabHandler(tabViewItem);
}
}
- (void)tabView:(NSTabView *)tabView willSelectTabViewItem:(NSTabViewItem *)tabViewItem {
[super tabView:tabView willSelectTabViewItem:tabViewItem];
if(tabViewItem.view) {
self.tabViewSizes[tabViewItem.identifier] = @(tabViewItem.view.frame.size);
}
if(self.willSelectTabHandler) {
self.willSelectTabHandler(tabViewItem);
}
}
- (void)_resizeWindowToFitTabView:(NSTabViewItem *)tabViewItem {
NSSize size = self.tabViewSizes[tabViewItem.identifier].sizeValue;
NSWindow *window = self.view.window;
NSRect contentRect = NSMakeRect(0, 0, size.width, size.height);
NSRect contentFrame = [window frameRectForContentRect:contentRect];
CGFloat toolbarHeight = CGRectGetHeight(window.frame) - CGRectGetHeight(contentFrame);
NSPoint newOrigin = NSMakePoint(CGRectGetMinX(window.frame), CGRectGetMinY(window.frame) + toolbarHeight);
NSRect newFrame = NSMakeRect(newOrigin.x,newOrigin.y, CGRectGetWidth(contentFrame), CGRectGetHeight(contentFrame));
[window setFrame:newFrame display:NO animate:YES];
}
@end

View File

@@ -24,9 +24,4 @@
@interface MPToolbarButton : NSButton
/* This methods ensure, that the button get sized correctly if used as the view in a NSToolbarItem*/
- (void)setControlSize:(NSControlSize)controlSize;
- (NSControlSize)controlSize;
@end

View File

@@ -37,43 +37,4 @@
return self;
}
- (void)setControlSize:(NSControlSize)controlSize {
NSImageRep *rep = [self.image bestRepresentationForRect:NSMakeRect(0, 0, 100, 100) context:nil hints:nil];
CGFloat scale = rep.size.width / rep.size.height;
switch (controlSize) {
case NSRegularControlSize:
self.image.size = NSMakeSize(16 * scale, 16);
break;
case NSSmallControlSize:
self.image.size = NSMakeSize(14 * scale, 14);
break;
case NSMiniControlSize:
self.image.size = NSMakeSize(8 * scale, 8);
default:
break;
}
if([self.superclass instancesRespondToSelector:@selector(setControlSize:)]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunguarded-availability"
super.controlSize = controlSize;
#pragma clang diagnostic pop
}
else {
self.cell.controlSize = controlSize;
}
}
- (NSControlSize)controlSize {
if([self.superclass instancesRespondToSelector:@selector(controlSize)]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunguarded-availability"
return super.controlSize;
#pragma clang pop
}
return self.cell.controlSize;
}
@end

View File

@@ -225,7 +225,7 @@ NSString *const MPToolbarItemIdentifierAutotype = @"TOOLBAR_AUTOTYPE";
MPToolbarItemIdentifierCopyPassword : [MPIconHelper icon:MPIconPassword],
MPToolbarItemIdentifierDelete: [MPIconHelper icon:MPIconTrash],
MPToolbarItemIdentifierAction: [NSImage imageNamed:NSImageNameActionTemplate],
MPToolbarItemIdentifierInspector: [MPIconHelper icon:MPIconInfo],
MPToolbarItemIdentifierInspector: [MPIconHelper icon:MPIconSidebar],
MPToolbarItemIdentifierHistory: [MPIconHelper icon:MPIconHistory],
MPToolbarItemIdentifierAutotype : [MPIconHelper icon:MPIconKeyboard]
};

View File

@@ -0,0 +1,21 @@
//
// MPTouchIdCompositeKeyStore.h
// MacPass
//
// Created by Julius Zint on 14.03.21.
// Copyright © 2021 HicknHack Software GmbH. All rights reserved.
//
#ifndef MPTouchIdCompositeKeyStore_h
#define MPTouchIdCompositeKeyStore_h
static NSMutableDictionary* touchIDSecuredPasswords;
@interface MPTouchIdCompositeKeyStore : NSObject
@property (class, strong, readonly) MPTouchIdCompositeKeyStore *defaultStore;
- (void) save:(NSData*) encryptedCompositeKey forDocumentKey:(NSString*) documentKey;
- (bool) load:(NSData**) encryptedCompositeKey forDocumentKey:(NSString*) documentKey;
@end
#endif /* MPTouchIdCompositeKeyStore_h */

View File

@@ -0,0 +1,64 @@
//
// MPTouchIdCompositeKeyStore.m
// MacPass
//
// Created by Julius Zint on 14.03.21.
// Copyright © 2021 HicknHack Software GmbH. All rights reserved.
//
#import "MPSettingsHelper.h"
#import "MPTouchIdCompositeKeyStore.h"
@implementation MPTouchIdCompositeKeyStore
+ (instancetype)defaultStore {
static MPTouchIdCompositeKeyStore *instance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[MPTouchIdCompositeKeyStore alloc] init];
if(touchIDSecuredPasswords == NULL) {
touchIDSecuredPasswords = [[NSMutableDictionary alloc]init];
}
});
return instance;
}
- (void) save: (NSData*) encryptedCompositeKey forDocumentKey:(NSString*) documentKey {
long touchIdMode = [NSUserDefaults.standardUserDefaults integerForKey:kMPSettingsKeyEntryTouchIdEnabled];
if (touchIdMode == NSControlStateValueMixed) {
[NSUserDefaults.standardUserDefaults removeObjectForKey:documentKey];
if(encryptedCompositeKey != NULL) {
[touchIDSecuredPasswords setObject:encryptedCompositeKey forKey:documentKey];
}
}
else if(touchIdMode == NSControlStateValueOn) {
[touchIDSecuredPasswords removeObjectForKey:documentKey];
if(encryptedCompositeKey != NULL) {
[NSUserDefaults.standardUserDefaults setObject:encryptedCompositeKey forKey:documentKey];
}
}
else {
[NSUserDefaults.standardUserDefaults removeObjectForKey:documentKey];
[touchIDSecuredPasswords removeObjectForKey:documentKey];
}
}
- (bool) load: (NSData**) encryptedCompositeKey forDocumentKey: (NSString*) documentKey {
long touchIdMode = [NSUserDefaults.standardUserDefaults integerForKey:kMPSettingsKeyEntryTouchIdEnabled];
NSData* transientKey = [touchIDSecuredPasswords valueForKey:documentKey];
NSData* persistentKey =[NSUserDefaults.standardUserDefaults dataForKey:documentKey];
if(transientKey == NULL && persistentKey == NULL) {
return false;
}
if(transientKey == NULL || persistentKey == NULL) {
*encryptedCompositeKey = transientKey == NULL ? persistentKey : transientKey;
return true;
}
if(touchIdMode == NSControlStateValueOn) {
*encryptedCompositeKey = persistentKey;
return true;
}
*encryptedCompositeKey = transientKey;
return true;
}
@end

View File

@@ -88,7 +88,7 @@
NSPanel *panel = [[NSPanel alloc] initWithContentRect:NSMakeRect(0, 0, 100, 100)
styleMask:NSWindowStyleMaskNonactivatingPanel|NSWindowStyleMaskTitled|NSWindowStyleMaskResizable
backing:NSBackingStoreRetained
backing:NSBackingStoreBuffered
defer:YES];
panel.level = NSScreenSaverWindowLevel;
panel.contentViewController = pickFieldViewController;
@@ -112,7 +112,7 @@
NSPanel *panel = [[NSPanel alloc] initWithContentRect:NSMakeRect(0, 0, 100, 100)
styleMask:NSWindowStyleMaskNonactivatingPanel|NSWindowStyleMaskTitled|NSWindowStyleMaskResizable
backing:NSBackingStoreRetained
backing:NSBackingStoreBuffered
defer:YES];
panel.level = NSScreenSaverWindowLevel;
panel.contentViewController = pickCharViewController;

Some files were not shown because too many files have changed in this diff Show More