Compare commits

..
1703 Commits
Author SHA1 Message Date
marc 43d5279acf package.json 2021-12-23 13:30:37 +01:00
Dimitri Witkowski e674607fce Merge pull request #1945 from dolfinus/develop
Install NativeMessagingHost for Chromium and Chrome dev/canary
2021-12-20 22:01:39 +01:00
dolfinus 2e6239f637 Install NativeMessagingHost for Chromium and Chrome dev/canary 2021-12-06 00:53:23 +03:00
antelle bcb8ddc17b fixed msteams html file name 2021-07-19 23:21:43 +02:00
antelle cd619582ec fixed variable usage 2021-07-13 19:05:25 +02:00
antelle 3b49562f64 added MS Teams apps 2021-07-13 19:04:27 +02:00
antelle 674ed2cc72 renames some ms teams constants 2021-07-11 16:22:38 +02:00
Dimitri Witkowski 5621fd8a06 Merge pull request #1856 from saulobejo/develop
added teams storage; added tenant id configuration for microsot
2021-07-11 16:18:53 +02:00
Saulo Alves af27e0b111 renamed teams to microsoft teams; fixed grunt prettier error in onedrive 2021-07-11 10:52:40 +02:00
Saulo Alves 5a78e12f7d added teams storage; added tenant id configuration for onedrive and teams 2021-07-11 00:56:51 +02:00
antelle 47b19d1d74 Merge branch 'master' into develop 2021-05-19 10:42:24 +02:00
antelle 070573e68a Merge branch 'release-1.18'
Build / web (push) Canceled after 0s
Build / linux (push) Canceled after 0s
Build / darwin (push) Canceled after 0s
Build / win32 (push) Canceled after 0s
Build / publish (push) Canceled after 0s
2021-05-19 10:35:35 +02:00
antelle 946d7769f1 bump version 2021-05-19 10:33:41 +02:00
antelle f0426a3ec2 fix #1820: minimize on close on macOS 2021-05-19 10:33:17 +02:00
antelle b2d67818a8 fix #1818: extension connection error if browser cannot be identified 2021-05-19 10:16:40 +02:00
antelle c0b159d824 fix #1824: saving KDBX3 files with compression disabled 2021-05-19 10:07:59 +02:00
antelle d7e11e20c1 Merge branch 'master' into develop 2021-05-14 21:18:46 +02:00
antelle d590318153 Merge branch 'release-1.18'
Build / web (push) Canceled after 0s
Build / linux (push) Canceled after 0s
Build / darwin (push) Canceled after 0s
Build / win32 (push) Canceled after 0s
Build / publish (push) Canceled after 0s
2021-05-14 21:02:12 +02:00
antelle 5816ca9c4d bump version 2021-05-14 21:01:43 +02:00
antelle 6627e8c0ec fix #1817: crash on files with large attachments as KDBX3 2021-05-14 21:00:43 +02:00
antelle 379e28e8a4 about version in the the bug report template 2021-05-14 20:56:48 +02:00
antelle 4fb25451a2 fix #1816: old Chromium support, such as Android Edge 2021-05-13 10:45:48 +02:00
antelle 58a6a97130 Merge branch 'master' into develop 2021-05-12 21:43:27 +02:00
antelle f59b846643 Merge branch 'release-1.18'
Build / linux (push) Canceled after 0s
Build / web (push) Canceled after 0s
Build / darwin (push) Canceled after 0s
Build / win32 (push) Canceled after 0s
Build / publish (push) Canceled after 0s
2021-05-12 21:40:25 +02:00
antelle 28d7dfeb67 bump version 2021-05-12 21:39:47 +02:00
antelle 6cc39d2107 fix #1808: restore KeeWeb from system tray on extension request 2021-05-12 21:38:54 +02:00
antelle a92a01095b fix #1814: option to disable auto-type title filter by default 2021-05-12 21:00:51 +02:00
antelle 3f4cddd2a2 fix #1811: app doesn't quit during update 2021-05-12 20:50:24 +02:00
antelle aa734ea976 fix #1813: fixed custom icon selection 2021-05-11 18:50:37 +02:00
antelle 30628004fd https link in the readme 2021-05-10 20:40:38 +02:00
antelle a6e87b52fd fix #1810: fixed the extension on old macOS starting 10.11 2021-05-10 20:40:30 +02:00
antelle 6d06d825e5 fixed donate button border 2021-05-10 18:12:11 +02:00
antelle 0800d5f33a Merge branch 'master' into develop 2021-05-09 23:25:27 +02:00
antelle 337ef44b56 Merge branch 'release-1.18'
Build / web (push) Canceled after 0s
Build / linux (push) Canceled after 0s
Build / darwin (push) Canceled after 0s
Build / win32 (push) Canceled after 0s
Build / publish (push) Canceled after 0s
2021-05-09 14:32:23 +02:00
antelle 70b4effde8 fix #1806: fixed a possible config loading error during startup 2021-05-09 14:31:58 +02:00
antelle 9e4c0f5c47 Merge branch 'release-1.18' 2021-05-09 14:12:50 +02:00
antelle 535cdc72f7 fix #1805: auto-unchecking auto-type filters if nothing found 2021-05-09 14:07:22 +02:00
antelle 8d258ecab2 fix #1804: entry table sizing in Firefox 2021-05-09 10:17:55 +02:00
antelle 3079e28f6f bump version 2021-05-09 10:09:26 +02:00
antelle 4970290614 fix #1804: filling OTP in browser extensions 2021-05-09 10:08:59 +02:00
antelle 6929931cae Merge branch 'master' into develop 2021-05-09 09:04:12 +02:00
antelle e348310602 Merge branch 'release-1.18'
Build / web (push) Canceled after 0s
Build / linux (push) Canceled after 0s
Build / darwin (push) Canceled after 0s
Build / win32 (push) Canceled after 0s
Build / publish (push) Canceled after 0s
2021-05-08 22:33:52 +02:00
antelle 7abbd2f253 bump version 2021-05-08 22:32:53 +02:00
antelle c56698492e fix #1802: opening files with saved keyfiles 2021-05-08 22:32:35 +02:00
antelle bc4c33fcbb Merge branch 'release-1.18'
Build / web (push) Canceled after 0s
Build / linux (push) Canceled after 0s
Build / darwin (push) Canceled after 0s
Build / win32 (push) Canceled after 0s
Build / publish (push) Canceled after 0s
2021-05-08 21:02:32 +02:00
antelle 05d5ac960c bump version 2021-05-08 21:01:00 +02:00
antelle 80331401b5 Merge branch 'master' into release-1.18 2021-05-08 21:00:47 +02:00
antelle b4459e1247 fixed entry attachments display 2021-05-08 21:00:38 +02:00
antelle 706c82d3ca fixed Windows code signing
Build / web (push) Canceled after 0s
Build / linux (push) Canceled after 0s
Build / darwin (push) Canceled after 0s
Build / win32 (push) Canceled after 0s
Build / publish (push) Canceled after 0s
2021-05-08 19:57:02 +02:00
antelle 0e1b086096 Merge branch 'develop' 2021-05-08 19:37:01 +02:00
antelle 80359c98f5 bump version 2021-05-08 19:35:51 +02:00
antelle 034e0ec2e3 always write version with 2 spaces 2021-05-08 19:35:36 +02:00
antelle cc6839d13e fixed native messaging host mode 2021-05-08 17:48:30 +02:00
antelle 0ce436c2e9 fixed phonetic password generation 2021-05-08 17:13:10 +02:00
antelle 966d814281 fixed removing an extra url 2021-05-08 16:59:36 +02:00
antelle c983bc10ab fixed git tag name 2021-05-08 16:11:26 +02:00
antelle d603398da0 upgrading node.js on ci 2021-05-08 14:21:56 +02:00
antelle 1404d2688f ci bugfixes 2021-05-08 14:14:00 +02:00
antelle c72158cf0d release name 2021-05-08 14:12:05 +02:00
antelle 1e6ed1308f fix eslint 2021-05-08 13:50:25 +02:00
antelle fae241373a fixed tests 2021-05-08 13:46:08 +02:00
antelle 2bf4cd83df upgrading node.js 2021-05-08 13:45:14 +02:00
antelle efd3290ee8 upgraded github release publishing 2021-05-08 13:35:03 +02:00
antelle aa729d9af8 don't log extension events when not connected 2021-05-08 11:46:53 +02:00
antelle 2d6d3658a1 fixed an error during exit without launcher 2021-05-08 11:42:08 +02:00
antelle 0cbdd6281a kdbxweb v2 2021-05-08 11:38:23 +02:00
antelle a845a42d0d up deps 2021-05-08 10:56:49 +02:00
antelle 60329e086a translated application menu on macOS 2021-05-08 10:37:24 +02:00
antelle a3174b96d7 up languages 2021-05-08 09:57:33 +02:00
antelle 29c00066bc Safari extension link 2021-05-08 09:53:57 +02:00
antelle b90ffc4d3f fix #1794: update installation on Windows when minimize instead of close is enabled 2021-05-06 20:44:09 +02:00
antelle 7e030320f5 option to auto-save on file change, fix #1364 2021-05-06 20:13:58 +02:00
antelle c96bcad32d release notes formatting 2021-05-05 19:56:29 +02:00
antelle a655cce195 removed file version fix 2021-05-05 18:49:24 +02:00
antelle aafb0e7964 editorconfig 2021-05-04 17:18:26 +02:00
antelle 288f7f117f removed an http link 2021-05-02 20:51:32 +02:00
antelle 125ac2eda8 wording 2021-05-02 20:43:44 +02:00
antelle ea80bfae07 fix #keeweb/keeweb-connect#3: extension manifest file name 2021-05-01 19:20:14 +02:00
antelle 5e727a3547 fixed native messaging host permissions 2021-04-30 10:16:30 +02:00
antelle 6672b60d0f fix #1779: don't copy passwords from the inline genertor in fields 2021-04-29 14:20:36 +02:00
antelle 09fe1a4649 fix #1780: custom icon selection issue 2021-04-29 14:16:39 +02:00
antelle e4fa4cc413 fixed selecting password as custom field 2021-04-29 14:02:42 +02:00
antelle 0be60475cf selecting other fields for browser extensions 2021-04-29 12:55:00 +02:00
antelle b7e53185b0 returning otp codes 2021-04-29 12:16:53 +02:00
antelle cd8c76b3eb up deps 2021-04-29 11:30:01 +02:00
antelle a1d7a1fe48 ignoring errors during usb init 2021-04-29 10:15:41 +02:00
antelle c48153819f checking all urls in the auto-type search 2021-04-29 09:18:32 +02:00
antelle d2d5590887 replaced a constant 2021-04-29 08:31:37 +02:00
antelle 65b319e127 extension ids constants 2021-04-29 08:29:33 +02:00
antelle b34c0dd34e ignoring custom websites in the selectiong pop-up 2021-04-28 23:47:56 +02:00
antelle ddc1a371bf increased the timeout 2021-04-28 23:40:37 +02:00
antelle a0c0b7b195 cancel button in the entry selection view 2021-04-28 23:37:15 +02:00
antelle b07cea9049 option to show an empty entry selection screen 2021-04-28 23:29:13 +02:00
antelle 991388d4cd removed debugging code 2021-04-28 23:09:24 +02:00
antelle 7adc77c823 closing the selection view on inactivity 2021-04-28 23:08:01 +02:00
antelle 550f93d4ae release notes
fix #874
2021-04-28 22:12:07 +02:00
antelle b43187e5b8 update deps again 2021-04-28 21:08:42 +02:00
antelle 6230710bb0 fixing build 2021-04-28 21:07:22 +02:00
antelle ff119cbc0a Revert "audit fix"
This reverts commit 2a2ec713
2021-04-28 21:05:22 +02:00
antelle 2a2ec713af audit fix 2021-04-28 21:04:37 +02:00
antelle 41eb560d1a fixed deps 2021-04-28 21:03:49 +02:00
antelle f7b9b91144 temporary safari link 2021-04-28 20:25:46 +02:00
antelle 97ab5d066e Added extension links 2021-04-28 20:22:21 +02:00
antelle 448e19d28c fixed entry searching with subdomains 2021-04-28 18:57:41 +02:00
antelle 391f2c9c00 fixed entry creation 2021-04-28 18:29:45 +02:00
antelle 18524ad9eb returning one matching entry automatically 2021-04-28 17:59:47 +02:00
antelle 732c35625b entry selection filters 2021-04-28 17:34:48 +02:00
antelle 95857450c2 focusing KeeWeb before entry selection 2021-04-28 12:04:54 +02:00
antelle 98ea7a542d extracted select-entry-filter 2021-04-28 11:29:48 +02:00
antelle 338f6d47d1 extracted entry selection view 2021-04-28 09:44:02 +02:00
antelle fdb492c572 don't prevent closing main window during auto-type 2021-04-28 08:25:18 +02:00
antelle ce3ff8c3d8 fixed extra file opened during auto-type 2021-04-28 08:23:15 +02:00
antelle 1789d9bb67 up deps 2021-04-28 07:47:13 +02:00
antelle 1883b527a4 fixed window blur during auto-type 2021-04-27 21:38:31 +02:00
antelle 2f4a9d450a displaying extension name in views 2021-04-27 20:01:53 +02:00
antelle 12fc33a15e fixed web extension focus 2021-04-27 19:38:27 +02:00
antelle e4693ecf61 updating entries 2021-04-27 19:15:03 +02:00
antelle c15d709db2 fixed table view column width 2021-04-27 16:23:49 +02:00
antelle e09040b0fb fixed auto-type from minimized state 2021-04-27 14:49:13 +02:00
antelle 4477c3fc2c get-logins messages 2021-04-27 14:29:00 +02:00
antelle f52a00a156 implemented set-login for extensions 2021-04-27 13:58:43 +02:00
antelle 946a063993 fixed data decryption error 2021-04-26 23:55:44 +02:00
antelle d3fcbcb6a5 fixed read passwords count display 2021-04-26 23:44:41 +02:00
antelle f91cfc0f79 processing triggerUnlock sent by the extension 2021-04-26 22:35:17 +02:00
antelle f0bbc54fd5 fixed extension version 2021-04-26 22:29:02 +02:00
antelle 3ca5f94b9b creating new groups form browser extensions 2021-04-26 20:47:43 +02:00
antelle 7a35ebec73 fixed a memory leak
see #1580
2021-04-26 19:20:29 +02:00
antelle 66d3623f90 implemented new group creation 2021-04-26 16:40:36 +02:00
antelle 8c9badd440 checking available files per connection 2021-04-26 15:36:21 +02:00
antelle e0d47a474d switching to the open view on request 2021-04-26 13:40:37 +02:00
antelle 1a8aff0594 fix eslint 2021-04-26 13:34:33 +02:00
antelle cf5e01c213 wording 2021-04-26 13:31:57 +02:00
antelle ffae956e21 removing empty websites 2021-04-26 13:30:12 +02:00
antelle 5c4cb7ff6d displaying extra websites as urls 2021-04-26 13:26:27 +02:00
antelle 7794c8b89b release notes 2021-04-26 12:49:59 +02:00
antelle bb78e8e8a7 adding multiple websites to entries 2021-04-26 12:49:25 +02:00
antelle 00a2a95adc fixed read passwords display 2021-04-26 12:22:35 +02:00
antelle e55dd47f6e don't hide keeweb after successful result 2021-04-26 12:16:22 +02:00
antelle 7b10bda0a4 eslint fix 2021-04-26 12:08:30 +02:00
antelle d5b9aefa01 unlocking on request from browser extension 2021-04-26 12:06:03 +02:00
antelle cdc3f5e1df displaying a message on the open screen 2021-04-26 11:51:24 +02:00
antelle 8fc6f49fb4 reworked unlocking files for auto-type and browser extension connection
fix #1768
2021-04-26 11:20:20 +02:00
antelle 29e5c14009 setting for saving credentials 2021-04-25 23:17:14 +02:00
antelle fe9ff205b9 wording 2021-04-25 23:02:02 +02:00
antelle 87b59eccee fixed extension connection on web 2021-04-25 20:38:49 +02:00
antelle 42cb5a6c36 editing file permissions in settings 2021-04-25 19:59:52 +02:00
antelle 9826965803 session management in settings 2021-04-25 18:08:16 +02:00
antelle 47153e41d3 extension connection timeout 2021-04-25 14:09:54 +02:00
antelle 677b428e63 all other files and all files 2021-04-25 13:50:03 +02:00
antelle 15936fcef0 extension connection dialog 2021-04-25 13:46:59 +02:00
antelle b2e828e7ef up native messaging host 2021-04-25 00:17:35 +02:00
antelle ac6e5a3ae8 fixed processing first message 2021-04-24 23:47:35 +02:00
antelle 3722477eea added a warning about extension association 2021-04-24 19:31:39 +02:00
antelle 72d0f76acc getting parent info for cmd 2021-04-24 10:48:28 +02:00
antelle b7333574aa replaced .exe in app name on windows 2021-04-24 10:38:43 +02:00
antelle 5caccbd1f5 getting appName 2021-04-24 10:26:07 +02:00
antelle 698b559935 up native-messaging-host 2021-04-24 10:06:55 +02:00
antelle 36d5e8f730 windows process information 2021-04-23 23:49:14 +02:00
antelle 233721bf51 extension installation on Windows 2021-04-23 23:17:35 +02:00
antelle 822602a38f added a note about windows-registry 2021-04-23 21:25:49 +02:00
antelle e69dbf697c up keeweb-native-modules 2021-04-23 21:17:11 +02:00
antelle 184d71a1b9 fixed firefox manifest 2021-04-21 23:30:32 +02:00
antelle ccb9b03287 creating native manifests 2021-04-21 22:23:17 +02:00
antelle dd4ad6d72b starting the extension host based on settings 2021-04-21 20:27:55 +02:00
antelle 195e2cc8f0 fixed exports 2021-04-21 20:09:26 +02:00
antelle ef573336d8 moved isDev to utils 2021-04-21 19:31:37 +02:00
antelle 9377a849f6 added native messaging host package 2021-04-21 19:28:44 +02:00
antelle 00ccbf4be2 deleted native-messaging-host 2021-04-20 17:07:50 +02:00
antelle 00159d26dc extracted protocolimpl 2021-04-19 23:40:57 +02:00
antelle b4f93adf05 reorganized imports a bit 2021-04-19 23:33:16 +02:00
antelle 5bbc9003f4 enable extension settings 2021-04-19 22:40:59 +02:00
antelle c4be926b7c better extension messages 2021-04-19 21:56:08 +02:00
antelle 147e3911f1 fixed no extensions message 2021-04-19 21:31:55 +02:00
antelle c7b814fc01 browser extension settings 2021-04-19 21:29:52 +02:00
antelle 8525571afc disabled the extension setting for mobile 2021-04-19 18:18:37 +02:00
antelle 5c5de91672 fixed links in desktop apps 2021-04-19 18:15:41 +02:00
antelle 7dbb0a2e8f added a missing whitespace 2021-04-18 21:42:22 +02:00
antelle 11b54ffdf9 wording 2021-04-18 21:39:24 +02:00
antelle 5d76ac33dd wording 2021-04-18 21:38:58 +02:00
antelle 8e92bf3766 kw.runtimeData api 2021-04-18 21:37:17 +02:00
antelle 56517eec62 typo 2021-04-18 21:35:45 +02:00
antelle ed56f0733e added an option to focus KeeWeb when the file is locked 2021-04-18 21:02:43 +02:00
antelle 3fd799ee74 browser extension settings page 2021-04-18 20:55:27 +02:00
antelle 4ed8a67eda simplified a condition 2021-04-18 18:57:38 +02:00
antelle cbb9a8dbd0 sending origin information in the first message 2021-04-18 18:50:03 +02:00
antelle 4280b84459 moved browser socket connection management to the main process 2021-04-18 14:26:45 +02:00
antelle e06e9ac1f8 moved ipc handlers setup to corresponding files 2021-04-18 11:50:11 +02:00
antelle 7bea4ad282 added team id to avoid the requirement for codesigning config 2021-04-17 20:33:37 +02:00
antelle 316c14d845 shorter socket name 2021-04-17 17:25:14 +02:00
antelle d17be63312 keeweb-browse => keeweb-connect 2021-04-17 17:00:14 +02:00
antelle 2c2253db31 renamed the extension 2021-04-17 16:57:06 +02:00
antelle a3128e56a3 client.supportsNotifications 2021-04-17 09:51:18 +02:00
antelle de0cf0ce67 fixed an empty notification about closing files 2021-04-17 09:28:25 +02:00
antelle e3f33b9d4c don't require client id for ping 2021-04-16 21:06:20 +02:00
antelle 27143e2663 fixed macos socket 2021-04-15 23:46:34 +02:00
antelle 566e2fb35d creating browser socket in a group container on macOS 2021-04-15 20:38:13 +02:00
antelle dc5ada1c04 etter error handling 2021-04-14 21:31:29 +02:00
antelle 603e698f5a fixed socket cleanup on windows 2021-04-14 21:26:58 +02:00
antelle f893dcb19a native messaging host tests 2021-04-14 21:11:24 +02:00
antelle 27b116798e tests fix 2021-04-14 20:41:45 +02:00
antelle ae932e5710 windows extension connection fixes 2021-04-14 20:34:03 +02:00
antelle bab5a979be windows compilation options 2021-04-13 23:37:43 +02:00
antelle 1b8c9a3e0c fixed linux helper paths 2021-04-13 23:03:38 +02:00
antelle 99d0fa30ed removed keeweb launching 2021-04-13 22:59:39 +02:00
antelle 5cc146481b fixed grunt-cmake 2021-04-13 22:55:38 +02:00
antelle 102da5cba1 signing the native messaging host 2021-04-13 22:40:35 +02:00
antelle d374eecb18 running cmake on build 2021-04-13 22:39:07 +02:00
antelle 08d31c0ffe don't launch keeweb if it's not running 2021-04-13 21:37:00 +02:00
antelle c62e40465a eslint 2021-04-13 20:43:34 +02:00
antelle 5367f32d5c reorganized app startup 2021-04-13 20:27:20 +02:00
antelle ad20698a42 deleted the browser extension setting 2021-04-13 20:27:07 +02:00
antelle e865d80a63 moved more code to protocol-impl 2021-04-12 23:42:42 +02:00
antelle 81a311e7fa refactored browser extension connector module 2021-04-12 23:37:08 +02:00
antelle 5397fa8fd3 create-group 2021-04-12 23:23:22 +02:00
antelle b9e08cd9e3 implemented get-database-groups 2021-04-12 23:05:57 +02:00
antelle fe86cd6320 native messaging on Firefox 2021-04-11 23:28:24 +02:00
antelle bba07bb83a fixed constant name 2021-04-11 19:52:49 +02:00
antelle 83a53ee1f0 error code property 2021-04-11 19:14:34 +02:00
antelle 23ba363a0d asking questions about accessing data in the extension 2021-04-11 18:59:33 +02:00
antelle 101aee81c0 added more browser extensions to the native host 2021-04-11 18:01:36 +02:00
antelle fa60d02129 option to debug browser extension transport 2021-04-11 17:59:05 +02:00
antelle 6a9e5fd801 always returning KeeWeb hash 2021-04-11 17:22:58 +02:00
antelle 12ae7845ec renamed the file 2021-04-11 15:41:39 +02:00
antelle 045e8ee96f fixed error codes 2021-04-11 15:04:04 +02:00
antelle 993f75b14e fixed some contract types 2021-04-11 14:53:56 +02:00
antelle b48f3746bc closing browser extension connections 2021-04-11 12:48:58 +02:00
antelle dcc477acbc tightened content security policy to prevent browser extension from adding scripts to KeeWeb 2021-04-11 11:44:51 +02:00
antelle 5f4f007b31 more extension logging 2021-04-11 10:17:02 +02:00
antelle 9d4788cb7c returning appName only for own extension 2021-04-10 23:37:24 +02:00
antelle 5a1380f9ef removed extra check 2021-04-10 23:36:21 +02:00
antelle 0d82aa26f3 checking own extension 2021-04-10 23:35:42 +02:00
antelle 05f2ec19f2 reorganized the extension connector code 2021-04-10 21:32:29 +02:00
antelle 25c3c9c565 connecting to the native app from the extension 2021-04-10 21:16:48 +02:00
antelle d6e7e3d4a0 reverted the timeout 2021-04-10 19:33:31 +02:00
antelle 6148112904 max 1 minute to connect to KeeWeb 2021-04-10 19:31:34 +02:00
antelle ba338e9282 launching keeweb 2021-04-10 19:29:24 +02:00
antelle 2e132690d1 fixed deletion 2021-04-10 18:59:58 +02:00
antelle 8f1b6ca3b7 removed some manual memory management 2021-04-10 18:54:15 +02:00
antelle 85d0252972 removed double stderr 2021-04-10 18:47:00 +02:00
antelle 077f72a0c5 printing stderr 2021-04-10 18:42:12 +02:00
antelle 25bec513f3 extracted some constants 2021-04-10 18:39:23 +02:00
antelle 0a6378d84c renamed the tests 2021-04-10 18:39:12 +02:00
antelle 1e6034ce37 native host tests 2021-04-10 18:38:27 +02:00
antelle ef6e5ebcbe added native messaging host 2021-04-10 17:00:10 +02:00
antelle 19a42b7463 fix #1783: crash after disabling USB devices on Linux 2021-04-10 00:19:58 +02:00
antelle 9d0e608454 Merge branch 'master' into develop
# Conflicts:
#	app/scripts/locales/base.json
#	app/scripts/storage/impl/storage-gdrive.js
#	package-lock.json
#	release-notes.md
2021-04-09 20:10:52 +02:00
antelle bd9a98dbfd fixed docker image tagging 2021-04-09 20:09:44 +02:00
antelle 0ffca3dfe4 npm audit fix 2021-04-09 19:03:02 +02:00
antelle 01958559ee fix #1767: updater issues on macOS 2021-04-09 19:01:55 +02:00
antelle bb4aef206a fixed wait-pid 2021-04-09 19:01:54 +02:00
antelle e74227b0db added --verbose option to the installer 2021-04-09 19:01:53 +02:00
antelle a47aec1cc4 bump version 2021-04-09 19:01:52 +02:00
antelle cd9d8cde3e release notes 2021-04-09 19:01:49 +02:00
antelle d4f68d5ec7 fix #1786: refresh_token in Google Drive 2021-04-09 19:01:48 +02:00
antelle a910cfcb35 fix #618: team drive support in Google Drive 2021-04-09 19:01:47 +02:00
antelle 962de503fd up kdbxweb 2021-04-09 19:01:27 +02:00
antelle f40e72c882 shared drives variable 2021-04-09 18:20:15 +02:00
antelle b7993e1d0e renamed team drives to shared drives 2021-04-09 18:19:26 +02:00
antelle d6e5e73e82 fixed refresh_token in Google Drive
see #1786
2021-04-08 23:07:19 +02:00
antelle 1794f87f99 fix #618: team drive support in Google Drive 2021-04-08 21:47:57 +02:00
antelle 81c7d57f30 localized templates folder name 2021-04-08 20:09:25 +02:00
antelle b4f0149bd8 saving extension name 2021-04-08 19:01:08 +02:00
antelle 87ec06eef0 browser extension: generate-password method 2021-04-08 18:10:48 +02:00
antelle c764548214 browser extension: generate-password method 2021-04-08 17:59:39 +02:00
antelle c78af7c3ad setting nonce in response payload 2021-04-08 17:36:42 +02:00
antelle f9cd0d4e29 browser extension: asking for user attention 2021-04-08 17:28:41 +02:00
antelle ee03435ca7 implemented lock-database 2021-04-07 22:49:23 +02:00
antelle a9b83256c6 returning only active db hashes 2021-04-07 22:07:16 +02:00
antelle 7086ddcf58 returning the list of hashes 2021-04-07 22:04:21 +02:00
antelle 26d226bb17 browser-extension: returning appName 2021-04-07 21:16:48 +02:00
antelle dc4742bf5c browser extension connector: implemented get-databasehash 2021-04-07 21:08:22 +02:00
antelle 933df5fae4 browser extension file notifications 2021-04-06 21:27:58 +02:00
antelle 4b17ac19dc browser extension backend 101 2021-04-06 20:10:42 +02:00
antelle 43f6a4f499 clone keeweb-browser in dev-env 2021-04-05 09:53:49 +02:00
antelle 076b99676d fix #1775: special error message for cases when Touch ID is changed after setup
also added Touch ID key deletion when it's disabled
2021-04-02 18:47:04 +02:00
antelle b3dfa05a4a added menu translations 2021-04-02 13:34:27 +02:00
antelle c5946b1a0b fixed default character count calculation in the generator 2021-04-01 21:57:42 +02:00
antelle 58a85eabdf fix #1774: password generator now includes all selected character ranges 2021-04-01 21:54:42 +02:00
Dimitri Witkowski 8a1d9b96dd Merge pull request #1770 from aslafy-z/patch-1
fix(docker): publish all docker image tags
2021-03-29 20:31:41 +02:00
Zadkiel 36a3d2f766 fix(docker): publish all docker image tags 2021-03-29 20:25:37 +02:00
antelle 68010076f9 renamed external model to otp-device 2021-03-28 19:05:20 +02:00
antelle 92da783e82 moved spawn to the main process 2021-03-28 18:41:31 +02:00
antelle 7d1e343d25 fixed wait-pid 2021-03-27 14:24:54 +01:00
antelle 84d17b7255 added --verbose option to the installer 2021-03-27 14:11:28 +01:00
antelle 64e06a32ec Merge branch 'master' into develop
# Conflicts:
#	package-lock.json
#	release-notes.md
2021-03-27 10:25:29 +01:00
antelle 4ee87e197d using new accounts ykman command
Build / publish (push) Canceled after 0s
Build / web (push) Canceled after 0s
Build / linux (push) Canceled after 0s
Build / darwin (push) Canceled after 0s
Build / win32 (push) Canceled after 0s
2021-03-27 09:19:20 +01:00
antelle cace667b26 release notes 2021-03-27 09:19:19 +01:00
antelle 67d3e28af7 bump version 2021-03-27 09:19:18 +01:00
antelle 3c5f4e7b84 release notes 2021-03-27 09:19:17 +01:00
antelle 8f913c737c removed debugging code from build 2021-03-27 09:19:16 +01:00
antelle 8ba147f52f fix #1762: line breaks in Markdown notes 2021-03-27 09:19:15 +01:00
antelle 9cfbd24b76 fix #1758: export format HTML issues 2021-03-27 09:19:14 +01:00
antelle 259abf6d25 added missing overflow to revealed passwords 2021-03-27 09:19:13 +01:00
antelle 8c59838a6f fix #1734: overlapping generator icon on password inputs 2021-03-27 09:19:12 +01:00
antelle f7d24c6379 fix #1725: setting expire date in the past 2021-03-27 09:19:11 +01:00
antelle 0f5466e075 fix #1755: calendar tooltips in different time zones 2021-03-27 09:19:10 +01:00
antelle 7ab0e83f55 ykman v4 support 2021-03-27 09:19:09 +01:00
antelle dc02ede8d7 up kdbxweb 2021-03-27 09:19:08 +01:00
antelle 42e484827f restored the missing disk icon 2021-03-27 09:19:07 +01:00
antelle 576c8f97bd removed dist from dev-env 2021-03-27 09:19:06 +01:00
antelle 808b4a687d fix #1762: line breaks in Markdown notes 2021-03-24 17:02:05 +01:00
antelle 954f2c235b fix #1758: export format HTML issues 2021-03-22 17:13:09 +01:00
antelle 51a7bbbfb8 added missing overflow to revealed passwords 2021-03-21 17:38:36 +01:00
antelle 9b5f5857bb fix #1734: overlapping generator icon on password inputs 2021-03-21 17:35:06 +01:00
antelle e66f52a8ce fix #1753: option to use short-lived tokens in cloud storages 2021-03-21 17:22:38 +01:00
antelle 8023bcea96 fix #1725: setting expire date in the past 2021-03-21 16:38:09 +01:00
antelle dfb7491503 fix #1755: calendar tooltips in different time zones 2021-03-21 16:36:18 +01:00
antelle b43d9c963a ykman v4 support 2021-03-20 22:45:42 +01:00
antelle 51c0637134 fixed list item size in firefox 2021-03-20 22:40:13 +01:00
antelle b16c23190b fixed scrolled entry modification 2021-03-20 20:26:29 +01:00
antelle fddf2892cd fix #1580: high memory usage on large files, virtual scrolling of entries 2021-03-20 19:17:57 +01:00
antelle 53b5715da0 up kdbxweb 2021-03-19 23:07:10 +01:00
antelle 3a79fcb366 optimized memory consumption for large files
see #1580
2021-03-19 22:52:41 +01:00
antelle 4df034ac55 restored the missing disk icon 2021-03-19 22:11:55 +01:00
antelle a0bb04fe3a removed dist from dev-env 2021-03-19 22:08:33 +01:00
antelle a923f28a8d Merge branch 'master' into develop
# Conflicts:
#	release-notes.md
2021-03-19 18:57:01 +01:00
antelle 78642f1c9b opening XML and CSV files using the Open button 2021-03-19 18:56:36 +01:00
antelle f8a85af859 Merge branch 'release-1.17' into master
Build / web (push) Canceled after 0s
Build / linux (push) Canceled after 0s
Build / darwin (push) Canceled after 0s
Build / win32 (push) Canceled after 0s
Build / publish (push) Canceled after 0s
2021-03-18 17:14:58 +01:00
antelle bdb5bd0428 bump version 2021-03-18 17:14:37 +01:00
antelle 9e07f55c12 fix #1749: auto-type freezes on macOS 2021-03-18 17:14:01 +01:00
antelle 6a3e129ed5 fixed update installation when minimize on close is enabled
see #1740
2021-03-15 19:31:40 +01:00
antelle 879ba17760 Merge branch 'master' into develop
# Conflicts:
#	release-notes.md
2021-03-14 21:17:26 +01:00
antelle 0d2107e72a Merge branch 'release-1.17' into master
Build / web (push) Canceled after 0s
Build / linux (push) Canceled after 0s
Build / darwin (push) Canceled after 0s
Build / win32 (push) Canceled after 0s
Build / publish (push) Canceled after 0s
2021-03-14 20:24:38 +01:00
antelle a23a47fded bump version 2021-03-14 20:23:03 +01:00
antelle 7737a29cca fix #1747: white screen in old Safari 2021-03-14 20:22:37 +01:00
antelle 34278b3bff fixed usb-detection link 2021-03-13 19:37:47 +01:00
antelle 40b0643eaa Merge branch 'master' into develop 2021-03-13 19:31:54 +01:00
antelle ae7f5fbff2 Merge branch 'release-1.17' into master
Build / publish (push) Canceled after 0s
Build / web (push) Canceled after 0s
Build / linux (push) Canceled after 0s
Build / darwin (push) Canceled after 0s
Build / win32 (push) Canceled after 0s
2021-03-13 17:46:55 +01:00
antelle 0a776c6a72 Merge branch 'release-1.17' into develop
# Conflicts:
#	release-notes.md
2021-03-13 17:31:05 +01:00
antelle 5caecb1c8f fix #1738: fixed auto-type on Linux with NumLock pressed 2021-03-13 14:27:48 +01:00
antelle 0def3f8b2d fix #1745: deleting selected text in auto-type selector 2021-03-13 10:11:32 +01:00
antelle 1593acd8e9 fixed auto-type searchbox clear button alignment 2021-03-13 10:01:51 +01:00
antelle da5553364a using proper call sequence in node-usb-detection 2021-03-12 23:37:29 +01:00
antelle b7c03490d8 bump version 2021-03-12 23:17:22 +01:00
antelle b8dd7b0f71 fix #1744, fix #1743: fixed crashes in the USB module on Windows 2021-03-12 23:06:19 +01:00
antelle e7a8d5232f Merge branch 'master' into develop
# Conflicts:
#	release-notes.md
2021-03-10 21:37:23 +01:00
antelle c638fa38e8 Merge branch 'release-1.17' into master
Build / web (push) Canceled after 0s
Build / linux (push) Canceled after 0s
Build / darwin (push) Canceled after 0s
Build / win32 (push) Canceled after 0s
Build / publish (push) Canceled after 0s
2021-03-10 19:07:57 +01:00
antelle f74b054f01 release date 2021-03-10 19:06:56 +01:00
antelle b7af33edae bump version 2021-03-10 19:01:00 +01:00
antelle 166211b6f8 fix #1735: issue with auto-typing some characters on Windows 2021-03-10 17:58:17 +01:00
antelle f8ec47bfdb release notes 2021-03-08 22:34:29 +01:00
antelle 4e84121553 cleaned up legacy auto-type 2021-03-08 22:29:59 +01:00
antelle ccf4ce8e58 package name 2021-03-07 16:25:07 +01:00
antelle 6ba3d44fa1 Merge branch 'master' into develop 2021-03-07 15:16:48 +01:00
antelle c03ed76fec increased memory limit
Build / web (push) Canceled after 0s
Build / linux (push) Canceled after 0s
Build / darwin (push) Canceled after 0s
Build / win32 (push) Canceled after 0s
Build / publish (push) Canceled after 0s
2021-03-07 14:35:27 +01:00
antelle 31214b10e7 Merge branch 'develop' into master 2021-03-07 14:23:29 +01:00
antelle 5bbc324b2e bump version 2021-03-07 14:22:49 +01:00
antelle 7dcb22950e fixed bump version 2021-03-07 14:22:41 +01:00
antelle 3c06f1f1a3 release date 2021-03-07 14:20:32 +01:00
antelle 6bcf5161b1 release notes 2021-03-07 11:14:34 +01:00
antelle ccc6765e2e release date 2021-03-07 10:56:18 +01:00
antelle 14d40d4e2d release notes 2021-03-07 10:55:41 +01:00
antelle 75d563b320 removed debugging code 2021-03-06 21:40:23 +01:00
antelle 2fdd53b55e removed debugging code 2021-03-06 21:30:51 +01:00
antelle 4ac16a6701 debugging patching on ci 2021-03-06 21:24:45 +01:00
antelle e998788d25 git+https 2021-03-06 21:05:54 +01:00
antelle e23b80b11b languages 2021-03-06 20:52:59 +01:00
antelle 7eb884dcb9 up deps 2021-03-06 20:17:47 +01:00
antelle 92397adbb3 eslint 2021-03-06 20:17:31 +01:00
antelle 828485789f ignore password quality warnings alert box 2021-03-06 19:19:23 +01:00
antelle 2f84474216 disabled draggable window on Windows 2021-03-06 11:38:05 +01:00
antelle 762aab397d fixes for custom titlebar 2021-03-06 11:35:14 +01:00
antelle b03cb4590f release notes 2021-03-05 22:12:09 +01:00
antelle 5d40831dd7 reverted debug code 2021-03-05 21:16:42 +01:00
antelle 0d291afb05 fix #1729: prevent double encoding move path 2021-03-05 21:16:12 +01:00
antelle e107c5c108 disabled auto-switching theme 2021-03-05 21:08:09 +01:00
antelle 44905e674d fixed titlebar events 2021-03-03 23:46:23 +01:00
antelle 5b790e711a added a logo on the custom titlebar for Windows 2021-03-03 23:42:41 +01:00
antelle 1a9c54b237 extracted the inline logo 2021-03-03 22:33:29 +01:00
antelle 0f4434a361 fix #689: custom title bar on Windows 2021-03-03 22:12:49 +01:00
antelle 7e2823903b up electron 2021-03-03 17:34:57 +01:00
antelle 92937dbb86 fix #1727: tabs in notes 2021-03-03 17:13:41 +01:00
antelle 0868efe095 added --native-module-host-process option 2021-03-02 21:17:04 +01:00
antelle 97374f63f9 Merge branch 'master' into develop
# Conflicts:
#	desktop/package-lock.json
#	package-lock.json
#	release-notes.md
2021-03-02 20:10:18 +01:00
antelle 69f7b02ce6 Merge branch 'release-1.16' into master
Build / web (push) Canceled after 0s
Build / linux (push) Canceled after 0s
Build / darwin (push) Canceled after 0s
Build / win32 (push) Canceled after 0s
Build / publish (push) Canceled after 0s
2021-03-02 19:21:21 +01:00
antelle b5ee682a41 bump version 2021-03-02 19:18:46 +01:00
antelle 70f82bdfd8 release date fix 2021-03-02 19:18:29 +01:00
antelle e70185560b release notes 2021-03-02 19:18:21 +01:00
antelle be4be0e7e8 fix #1715: storage authentication in Epiphany browser 2021-03-02 19:17:42 +01:00
antelle b9a5c64113 fix #1713: OneDrive authentication on web 2021-03-02 19:17:36 +01:00
antelle 215f398547 fix #1726: search in protected fields 2021-03-02 19:17:29 +01:00
antelle ace18f9d95 fix #1715: storage authentication in Epiphany browser 2021-03-01 18:06:45 +01:00
antelle c4ec91f61a fix #1713: OneDrive authentication on web 2021-03-01 18:03:13 +01:00
antelle a4881419df fix #1726: search in protected fields 2021-03-01 17:55:08 +01:00
antelle 839359a794 removed a readme 2021-03-01 17:53:20 +01:00
antelle d4d9b7c7a7 readme about translations 2021-02-26 18:54:43 +01:00
antelle d4526c0c8a release notes 2021-02-26 18:48:18 +01:00
Dimitri Witkowski 78f0bc6f02 Merge pull request #1721 from enter-is/develop
Option to minimize KeeWeb on copy
2021-02-26 18:46:43 +01:00
is ad3f5afeba Option to minimize KeeWeb on copy
Code review changes: https://github.com/keeweb/keeweb/pull/1721

https://github.com/keeweb/keeweb/issues/1718
2021-02-23 08:43:01 +02:00
is 7c4326939a Option to minimize KeeWeb on copy
https://github.com/keeweb/keeweb/issues/1718
2021-02-22 15:02:42 +02:00
antelle e5428b67b8 npm 2021-02-14 11:42:10 +01:00
antelle 59616bd8af disabled touch id check 2021-02-14 11:36:20 +01:00
antelle fdc9ac95d2 up native-modules 2021-02-13 21:06:14 +01:00
antelle a8f0d1af62 extended the oauth fix to iOS, see #1711 2021-02-12 20:14:21 +01:00
antelle f6e377f222 fix #1711: workaround for Dropbox on iOS PWA 2021-02-12 20:14:07 +01:00
antelle c43d7ab92a extended the oauth fix to iOS, see #1711 2021-02-12 09:34:42 +01:00
antelle 0464e1de5c fix #1711: workaround for Dropbox on iOS PWA 2021-02-11 23:01:28 +01:00
antelle 7a7381eac0 don't spawn another process 2021-02-09 21:38:49 +01:00
antelle 1379db1e92 fixed yubikey touch 2021-02-09 21:37:54 +01:00
antelle ee10894f5f added an option to prevent another process from being created 2021-02-09 20:19:12 +01:00
antelle 87d760708d removed an extra code 2021-02-09 19:54:30 +01:00
antelle ec7155809b fixed native module helper 2021-02-08 22:49:53 +01:00
antelle 5af7837468 patching electron 2021-02-06 14:46:24 +01:00
antelle d3f79af2ab up 2021-02-06 14:25:12 +01:00
antelle a6c0fc3984 option do disable caching files in offline storage
fix #404, fix #1115
2021-02-06 13:53:12 +01:00
antelle 56604de7f1 up deps 2021-02-06 13:24:59 +01:00
antelle d5e6199775 added linux dependencies 2021-02-04 21:30:52 +01:00
antelle 15920abcf7 replaced a year 2021-02-04 21:09:21 +01:00
antelle 88205d716a new npm 2021-02-04 21:05:26 +01:00
antelle fa1a16f140 added an explanation about auto-type issues on macOS 2021-02-04 20:54:13 +01:00
antelle 4f8075ca6c package-lock 2021-02-04 19:47:15 +01:00
antelle 2615d0644d up 2021-02-03 23:59:15 +01:00
antelle d2686937fd fixed linux build 2021-02-03 22:00:03 +01:00
antelle b60307e28b removed com.apple.security.get-task-allow entitlement 2021-02-03 21:58:49 +01:00
antelle 08d49ddc54 fix #679, fix #1383: Touch ID on macOS 2021-02-03 20:30:59 +01:00
antelle 4cdc80e530 Touch ID settings, see #679 2021-02-01 22:24:53 +01:00
antelle acd360efb9 cleaned up old touch id implementation 2021-02-01 21:08:02 +01:00
antelle 87ad89beeb fix #1697: creating files with Argon2id KDF 2021-02-01 17:25:46 +01:00
antelle c2663ca7d8 new completion page after storage provider authentication 2021-01-31 13:24:49 +01:00
antelle 4e58285cc2 using batch text entry 2021-01-31 12:27:20 +01:00
antelle ef354fb8af up deps 2021-01-31 00:47:27 +01:00
antelle 79ce535d4a up deps 2021-01-31 00:20:34 +01:00
antelle 50c43c4408 year 2021-01-30 23:41:32 +01:00
antelle 8fdec5aadc added a module link 2021-01-30 21:40:00 +01:00
antelle 73eccd5308 added a message about delay 2021-01-30 21:37:09 +01:00
antelle 4449677e36 entering text as key codes 2021-01-30 21:34:08 +01:00
antelle 8dc3a4b51f fixed vkey 2021-01-30 20:29:26 +01:00
antelle cd2de3a1db native auto type: unpressing keys 2021-01-30 20:22:13 +01:00
antelle 1fa0eebc3b changed ipc method naming convention 2021-01-30 18:39:25 +01:00
antelle e13002bab3 typing key codes 2021-01-30 18:24:42 +01:00
antelle a750e80ea1 auto-type progress 2021-01-30 16:00:57 +01:00
antelle 66e1b0a089 first auto-type emitter implementation 2021-01-30 15:37:25 +01:00
antelle 00c0b3f88c native auto-type helper implementation 2021-01-30 14:55:00 +01:00
antelle 674311cb4b native auto-type methods 2021-01-30 14:16:32 +01:00
antelle f54b8e00e1 up deps 2021-01-30 14:03:59 +01:00
antelle c1beac5d0d up native-modules 2021-01-30 13:18:11 +01:00
antelle 7123345341 cleaned up useless conditions 2021-01-28 08:08:11 +01:00
antelle 0e2475e667 cleanup 2021-01-17 08:20:08 +01:00
antelle acf1f1146d removed other links 2021-01-17 08:14:42 +01:00
antelle d136fa4fdf disabled discussions 2021-01-17 08:14:01 +01:00
antelle 61067391b6 added a link to node-secure-enclave 2021-01-10 17:23:23 +01:00
antelle affebb1ba4 progress logging 2021-01-10 17:16:21 +01:00
antelle cbffa3d4ef message formatting 2021-01-10 17:11:47 +01:00
antelle 6ef5ae2517 separated encrypt and decrypt 2021-01-10 16:56:53 +01:00
antelle 9701496897 better message 2021-01-10 16:40:16 +01:00
antelle 22d6a3011f added a string for touch id 2021-01-10 16:31:50 +01:00
antelle d22ddd99f6 secure enclave support for #679 2021-01-10 14:31:33 +01:00
antelle 4e8648fca0 using the provisioning profile on ci 2021-01-10 12:23:18 +01:00
antelle 9f49c357e9 using provisioning profile for codesigning macos apps 2021-01-10 12:16:27 +01:00
antelle d318467039 added a possibility to build a signed desktop app with npm dev-desktop-macos-signed 2021-01-10 11:55:00 +01:00
antelle b05c25ac1a up keeweb-native-modules 2021-01-10 11:36:51 +01:00
antelle 5dd0d51514 removed endswith 2021-01-10 09:59:51 +01:00
antelle c7574a6b83 debug message in the installer 2021-01-10 09:41:30 +01:00
antelle ab64e9343b sleep time 2021-01-10 09:36:34 +01:00
antelle b82cb0e849 fixed Windows update installation 2021-01-10 09:28:09 +01:00
antelle c44a8fab42 fixed update buttons margin 2021-01-10 09:25:12 +01:00
antelle 9a75eb0a22 removed a newline 2021-01-10 00:17:14 +01:00
antelle f994278a8b windows update installer spaces fix 2021-01-10 00:16:45 +01:00
antelle bd882d0e17 fixed windows update installer 2021-01-10 00:14:28 +01:00
antelle fddf62409a fixed updater settings view 2021-01-09 23:04:22 +01:00
antelle a8967ac764 timeout before copying files in the updater 2021-01-09 22:10:39 +01:00
antelle 20bc254a42 fixed windows uninstaller 2021-01-09 21:52:38 +01:00
antelle e298d5fbd8 ignoring cancellation errors 2021-01-09 21:37:20 +01:00
antelle ff54c2070d fixed the macos updater 2021-01-09 21:34:59 +01:00
antelle e092caa2ef better syntax 2021-01-09 18:48:48 +01:00
antelle feb44be9d0 disable updater on Linux 2021-01-09 18:00:19 +01:00
antelle a43a2e8ce2 checking minVersion against app version 2021-01-09 17:53:13 +01:00
antelle 6fcf77829d using ES5 in the installer 2021-01-09 17:41:34 +01:00
antelle 733833e8a4 fix #1661: using the new Windows installer 2021-01-09 17:15:50 +01:00
antelle 890f998fe0 updating support in win32 installer 2021-01-09 17:14:56 +01:00
antelle 28c708f599 moved desktop scripts 2021-01-09 13:30:19 +01:00
antelle f1e536cbcf moved icons to a folder 2021-01-09 13:27:28 +01:00
antelle 8dc7ad4f01 renamed a module 2021-01-09 13:26:19 +01:00
antelle 43c8976282 fixed a typo 2021-01-09 13:24:50 +01:00
antelle 8ee63ccc24 always using updater cache 2021-01-09 13:21:37 +01:00
antelle 2900fe07bf fixed app launch 2021-01-09 13:19:24 +01:00
antelle 1d572d1fa9 installing updates on macos 2021-01-09 13:15:25 +01:00
antelle 21b8e9ae8f removed globals 2021-01-09 11:50:40 +01:00
antelle cb77b7fc1e moved the installer script 2021-01-09 11:49:54 +01:00
antelle 763141592f fixed dev build 2021-01-09 11:48:40 +01:00
antelle 09fcddfad2 removed an old script 2021-01-09 11:44:52 +01:00
antelle b8ce1b5cc1 macos installer 2021-01-09 11:44:13 +01:00
antelle 6a34fffcc4 more options for auto-lock timeout 2021-01-08 22:56:48 +01:00
antelle 75fa636366 disabled desktop update archives 2021-01-08 22:54:45 +01:00
antelle bee96ebf15 reading update.json 2021-01-07 23:00:16 +01:00
antelle 9ec23fac5d semver test 2021-01-07 22:59:07 +01:00
antelle 2a7cd3574d update.json 2021-01-07 22:05:04 +01:00
antelle 4f96629e22 simplified perf-tracker 2021-01-07 20:54:00 +01:00
antelle 74bd270423 rename 2021-01-07 20:52:52 +01:00
antelle 0469f28a54 removed main.js 2021-01-07 20:52:43 +01:00
antelle a9c2da3fdb Merge branch 'master' into develop
# Conflicts:
#	release-notes.md
2021-01-07 20:01:20 +01:00
antelle 2ec37c3ece fixed a js error 2021-01-02 10:40:24 +01:00
antelle ef812c5697 updated keeweb-plugin dev certificate 2021-01-02 10:38:12 +01:00
antelle 8ab4e7c433 twitter link 2021-01-01 20:06:21 +01:00
antelle 23bb30be92 issue links 2021-01-01 19:57:42 +01:00
antelle a13d44d560 discussions link 2021-01-01 19:55:30 +01:00
antelle 42b5b002cc Merge branch 'release-1.16' into master
Build / darwin (push) Canceled after 0s
Build / web (push) Canceled after 0s
Build / linux (push) Canceled after 0s
Build / win32 (push) Canceled after 0s
Build / publish (push) Canceled after 0s
2020-12-31 17:26:37 +01:00
antelle f889488915 bump version 2020-12-31 17:26:18 +01:00
antelle 57f3a287c2 Merge branch 'release-1.16' into master 2020-12-31 17:25:58 +01:00
antelle 143b1a73f7 fix #1671: new lines removal issue in notes 2020-12-31 17:24:59 +01:00
antelle 54a1860398 removed an extra output 2020-12-30 18:17:46 +01:00
antelle 014b6b2319 added --commit-sha 2020-12-30 18:12:28 +01:00
antelle 33763ab865 fix #1670: building without git 2020-12-30 17:46:16 +01:00
antelle 5f5ea892a3 Merge branch 'master' into develop 2020-12-30 13:30:40 +01:00
antelle a3fc2b2cdd debugging windows code signing
Build / web (push) Canceled after 0s
Build / linux (push) Canceled after 0s
Build / darwin (push) Canceled after 0s
Build / win32 (push) Canceled after 0s
Build / publish (push) Canceled after 0s
2020-12-30 13:30:11 +01:00
antelle 2cad70dae0 uploading artifacts before virustotal checks 2020-12-30 13:01:55 +01:00
antelle fb56ba2f0d Merge branch 'master' into develop
# Conflicts:
#	release-notes.md
2020-12-30 13:01:12 +01:00
antelle 7c2b7a09f8 Merge branch 'master' into release-1.16 2020-12-30 13:00:41 +01:00
antelle abf5531fc5 fixed another virustotal check failure 2020-12-30 12:52:48 +01:00
antelle 18775e3cea fixed virustotal check failure 2020-12-30 12:44:48 +01:00
antelle 9d5e7be105 Merge branch 'release-1.16' into master 2020-12-30 11:35:50 +01:00
antelle eed647c867 bump version 2020-12-30 11:34:43 +01:00
antelle 072271bbe6 languages 2020-12-30 11:34:06 +01:00
antelle a84499d7d4 upgraded vulnerable dependencies 2020-12-30 11:31:37 +01:00
antelle c06db5a2b7 fix #1668: replacing more bad characters in entry fields 2020-12-30 11:30:17 +01:00
antelle fc737b1f51 fix #1665: removed a package.json dependency from keeweb-plugin 2020-12-26 11:18:48 +01:00
antelle 4f068008bd fixed issues link color 2020-12-20 18:06:20 +01:00
antelle 953f6dc61f option to disable entropy-based checks 2020-12-20 17:53:43 +01:00
antelle 01fac1f0ca password quality warnings 2020-12-20 17:44:27 +01:00
antelle 1796ac743d fixed dropdown 2020-12-19 17:33:19 +01:00
antelle 60329b3cab made the light blue background a bit better 2020-12-19 16:58:25 +01:00
antelle f489eca5c2 fix #1505: pre-selecting first field in auto-type dropdown 2020-12-19 16:47:37 +01:00
antelle 1617cae518 fixed app startup background color 2020-12-19 16:39:18 +01:00
antelle 6c7b99af58 fix #1655: separated custom icons to make the download and selection buttons more visible 2020-12-19 16:30:03 +01:00
antelle ddd242b9df fix #1655: selecting downloaded favicon automatically 2020-12-19 16:29:19 +01:00
antelle c24fe2806c contrast theme position 2020-12-19 14:05:56 +01:00
antelle 8da0a2e239 more themes 2020-12-19 14:00:51 +01:00
antelle 8aff64ce47 removed an extra border on the open view 2020-12-19 14:00:42 +01:00
antelle 677f1ce75f fix #1584: automatically switching between dark and light theme 2020-12-19 12:14:32 +01:00
antelle f99ff95a57 Merge branch 'master' into develop
# Conflicts:
#	release-notes.md
2020-12-18 20:32:44 +01:00
antelle 7a522acdd9 Merge branch 'release-1.16' into master
Build / web (push) Canceled after 0s
Build / linux (push) Canceled after 0s
Build / darwin (push) Canceled after 0s
Build / win32 (push) Canceled after 0s
Build / publish (push) Canceled after 0s
2020-12-18 20:30:46 +01:00
antelle 9888a0cf5b bump version 2020-12-18 20:27:19 +01:00
antelle 9b586f7059 bump version 2020-12-18 20:27:13 +01:00
antelle 90666cea99 GitHub funding link 2020-12-18 20:26:36 +01:00
antelle cabf0d388d using custom OneDrive without a secret 2020-12-18 20:17:34 +01:00
antelle 39a33bd77a a bit more padding in advanced search options 2020-12-17 22:38:39 +01:00
antelle f184915849 fix #1657: clear searchbox button 2020-12-17 22:22:00 +01:00
antelle 683b0bc4e6 Merge branch 'master' into develop 2020-12-17 21:15:11 +01:00
antelle 212042556f Merge branch 'release-1.16' into master
Build / web (push) Canceled after 0s
Build / linux (push) Canceled after 0s
Build / darwin (push) Canceled after 0s
Build / win32 (push) Canceled after 0s
Build / publish (push) Canceled after 0s
2020-12-17 19:29:14 +01:00
antelle cc4aa6fc1a bump version 2020-12-17 19:28:45 +01:00
antelle b4b6ef3206 calling oauth authorize again if the refresh token is expired 2020-12-17 19:25:36 +01:00
antelle ccfd5126bc release notes 2020-12-16 21:15:40 +01:00
antelle b733b43f8b release notes 2020-12-16 21:15:27 +01:00
antelle 3c0693fdd9 skip VirusTotal checks in ci-sandbox 2020-12-16 21:14:39 +01:00
antelle 938f2be487 passing sha to VirusTotal 2020-12-16 21:12:48 +01:00
antelle 9f2a09cc97 optional oauth secret 2020-12-16 20:32:48 +01:00
antelle 27d5fc4cba running VirusTotal checks on CI, see #1656 2020-12-16 20:15:14 +01:00
antelle 251b763ea9 fix #1656: false positive report on VirusTotal 2020-12-16 18:53:15 +01:00
antelle 8a07162e6b fixed checkbox positioning in settings 2020-12-12 11:02:56 +01:00
antelle 4097d81b8a fixed whitespace replacing in templates 2020-12-12 10:59:34 +01:00
antelle bf2d72745a removed the runtime chunk 2020-12-12 10:38:39 +01:00
antelle acc60e6297 Merge branch 'master' into develop 2020-12-10 23:16:06 +01:00
antelle 211b058686 Merge branch 'release-1.16' into master
Build / web (push) Canceled after 0s
Build / linux (push) Canceled after 0s
Build / darwin (push) Canceled after 0s
Build / win32 (push) Canceled after 0s
Build / publish (push) Canceled after 0s
2020-12-10 20:35:28 +01:00
antelle 95c077a0ba bump version 2020-12-10 20:34:11 +01:00
antelle 0b70017780 fix #1650: keyfiles stored in the app can't be used 2020-12-10 20:33:48 +01:00
antelle 513e258869 removed an unused workflow 2020-12-10 19:18:36 +01:00
antelle 7cd046ecc0 Merge branch 'release-1.16' into master
Build / web (push) Canceled after 0s
Build / linux (push) Canceled after 0s
Build / darwin (push) Canceled after 0s
Build / win32 (push) Canceled after 0s
Build / publish (push) Canceled after 0s
2020-12-10 19:11:47 +01:00
antelle 220a27e030 keyx 2020-12-10 19:10:18 +01:00
antelle 3728fbc367 bump version 2020-12-10 19:08:20 +01:00
antelle 6d41c71542 up 2020-12-10 19:07:54 +01:00
antelle a1b4dde3e3 release date 2020-12-10 19:06:03 +01:00
antelle 677586e882 fix #1649: missing Argon2 options 2020-12-10 17:41:59 +01:00
antelle 3177a87690 possibility to use V2 keyfiles (.keyx) 2020-12-09 19:21:18 +01:00
antelle f8fda777db Merge branch 'master' into develop 2020-12-06 10:31:16 +01:00
antelle e955c3ddc1 fix #1575: auto-type menu scrolling 2020-12-06 10:30:54 +01:00
antelle 7e36418276 fixed a js error in closing all files 2020-12-05 15:24:45 +01:00
antelle e5616dffa7 more precise license wording 2020-12-04 21:01:08 +01:00
antelle be3087d2cc removed a non-needed link 2020-12-04 20:58:10 +01:00
antelle 396721fce6 fixed a wrong copyright symbol 2020-12-04 20:57:36 +01:00
antelle d49af938d9 switched to setup-gcloud 2020-12-04 20:22:42 +01:00
antelle d2ae8522b5 release notes 2020-12-04 18:01:09 +01:00
antelle a3e27709d0 fixed local file icon 2020-12-04 16:48:48 +01:00
antelle a245553cad Merge branch 'release-1.16' into master
Build / web (push) Canceled after 0s
Build / linux (push) Canceled after 0s
Build / darwin (push) Canceled after 0s
Build / win32 (push) Canceled after 0s
Build / publish (push) Canceled after 0s
2020-12-04 16:07:25 +01:00
antelle 8bcdc6d109 bump version 2020-12-04 16:06:10 +01:00
antelle 8a1b28a793 up 2020-12-04 16:05:45 +01:00
antelle 90b236e6f9 Merge branch 'release-1.16' into master 2020-12-04 16:03:42 +01:00
antelle 804b8cf17b release notes 2020-12-04 16:03:14 +01:00
antelle ed3eefbbfc Merge branch 'master' into release-1.16 2020-12-04 16:01:55 +01:00
antelle 51564056a1 Merge branch 'develop' into master 2020-12-04 16:00:48 +01:00
antelle 4884caadd4 fixed icon positioning in links 2020-12-04 09:19:19 +01:00
antelle e129e52e01 fixed icon positioning in links 2020-12-04 09:18:23 +01:00
antelle 893a0f43c1 release date 2020-12-04 08:55:22 +01:00
antelle 083cbe9840 release date 2020-12-04 08:16:27 +01:00
antelle a7fcbae65f up native modules 2020-12-04 07:25:29 +01:00
antelle 7ae80c2e7c copyrights 2020-12-03 23:57:40 +01:00
antelle f1ede2b876 license year 2020-12-03 23:31:42 +01:00
antelle 8c51adbca1 up node_modules 2020-12-03 22:12:52 +01:00
antelle 446f293da0 rebuilt KeeWebHelper as a universal app 2020-12-03 22:12:42 +01:00
antelle bbd7f9c6d6 keyfile paths are saved by default, see #325 2020-12-03 21:09:51 +01:00
antelle 9e5fb90bd6 Argon2id KDF support 2020-12-03 20:22:33 +01:00
antelle 2ed735ad95 fixed list borders on mobile 2020-12-02 21:01:56 +01:00
antelle 00be6f0181 fixed default theme 2020-12-01 19:53:18 +01:00
antelle 29a4d367f9 added missing rgba 2020-12-01 19:42:37 +01:00
antelle df43c61785 fix #1645: color contrast on the selection 2020-12-01 19:28:07 +01:00
antelle 464c49257a building arm64.dmg 2020-11-30 21:16:17 +01:00
antelle bd4a6d0eee fixed arm64 2020-11-30 21:03:20 +01:00
antelle 9410fc6a8c apple silicon build 2020-11-30 20:52:09 +01:00
antelle bd400c0797 up native modules 2020-11-30 18:51:26 +01:00
Dimitri Witkowski 54c721c265 Merge pull request #1642 from PeterDaveHello/DockerfileRefactor
Clean up apt local cache in Dockerfile
2020-11-30 07:49:33 +01:00
Peter Dave Hello 94cfa4f3d4 Replace ADD with COPY instruction in Dockerfile
Reference:

- https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#add-or-copy

> For other items (files, directories) that do not require ADD’s tar
> auto-extraction capability, you should always use COPY.
2020-11-30 10:11:32 +08:00
antelle f21ef7f444 fixed min electron version 2020-11-29 19:58:34 +01:00
Dimitri Witkowski 66a0cf4782 Merge pull request #1639 from PeterDaveHello/patch-3
Ask apk to leave no cache in Dockerfile
2020-11-29 18:57:12 +01:00
Dimitri Witkowski 52f27ce743 Merge pull request #1638 from PeterDaveHello/patch-2
Clean up apt local cache in Dockerfile
2020-11-29 18:56:38 +01:00
Peter Dave Hello 57296ba313 Ask apk to leave no cache in Dockerfile
This will make the image smaller
2020-11-30 01:51:47 +08:00
Peter Dave Hello 47dc1727df Clean up apt local cache in Dockerfile
This will make the image smaller
2020-11-30 01:49:53 +08:00
antelle cd9fe46fdb fixed jumping title in Safari 2020-11-29 18:06:56 +01:00
antelle 775cdf237c fix #1637: git commit in the About box 2020-11-29 17:10:56 +01:00
antelle 63367998bf Merge branch 'develop' into master
Build / web (push) Canceled after 0s
Build / linux (push) Canceled after 0s
Build / darwin (push) Canceled after 0s
Build / win32 (push) Canceled after 0s
Build / publish (push) Canceled after 0s
2020-11-29 15:06:59 +01:00
antelle 5d3e110a9e release notes 2020-11-29 15:05:47 +01:00
antelle 42267eaef8 languages 2020-11-29 15:05:15 +01:00
antelle b716599c90 up deps 2020-11-29 14:53:21 +01:00
antelle 6d80de9216 bump version 2020-11-29 14:48:43 +01:00
antelle 212dc99cec updated screenshot 2020-11-29 14:44:39 +01:00
antelle 6f4f8ec1ea action names 2020-11-29 14:12:42 +01:00
antelle 24c64daa49 gcloud action 2020-11-29 13:29:01 +01:00
antelle bdd9a51d25 style fixes 2020-11-29 13:12:32 +01:00
antelle f27862b036 mac menubar icon 2020-11-29 12:17:49 +01:00
antelle f7e9f725b0 bugfixes 2020-11-29 11:10:34 +01:00
antelle 4ee430284b some fixes 2020-11-29 00:19:49 +01:00
antelle 96458048fc fixed menu color 2020-11-28 23:43:56 +01:00
antelle a31f9d5a50 new themes 2020-11-28 23:38:12 +01:00
antelle 33d5f0b5bb some icon fixes 2020-11-28 12:30:46 +01:00
antelle ec43f0a549 fixed themes grid size 2020-11-27 22:28:10 +01:00
antelle 8e0dc326cb better theme selector 2020-11-27 21:17:27 +01:00
antelle 9994c87446 default locale in settings 2020-11-27 20:21:24 +01:00
antelle 647ce573b0 set the default language to en-US to reflect what it is 2020-11-27 18:47:55 +01:00
antelle 1ca4ead313 release notes 2020-11-27 18:40:52 +01:00
antelle 1ef5ffab52 Merge branch 'MrSnix-feature/time-format' into develop 2020-11-27 18:40:05 +01:00
antelle f4f2ddfb3c fix 2020-11-27 18:38:11 +01:00
antelle 650b4805be fixed test runner fatal error reporting 2020-11-26 23:34:08 +01:00
antelle 22754f32ec revert 2020-11-26 23:33:37 +01:00
antelle 85a67b533a fixed test runner fatal error reporting 2020-11-26 22:27:20 +01:00
antelle 974dbd224a release notes 2020-11-26 22:04:06 +01:00
antelle b8c7a8b936 fixed the yubikey icon 2020-11-26 22:04:06 +01:00
antelle 86844064db updated macOS helper icon 2020-11-26 22:04:05 +01:00
antelle 0c9b9a1b97 removed app icon for macos 2020-11-26 22:04:01 +01:00
Giuseppe 0a9846b86f Fix: wrong argument passed 2020-11-26 21:41:24 +01:00
Giuseppe 96ee17b8cc Moved date-format.js to comp/util/ 2020-11-26 21:19:36 +01:00
Giuseppe 4b65792585 Tests now are UTC based to avoid locale conflicts 2020-11-26 20:48:43 +01:00
Giuseppe 32b871e338 Forgot to remove useless import 2020-11-26 11:45:47 +01:00
Giuseppe 46ddb725db Initial commit 2020-11-26 11:32:10 +01:00
antelle d0fdada9f7 release notes 2020-11-25 23:45:14 +01:00
antelle a343853b38 fixed the yubikey icon 2020-11-25 23:33:45 +01:00
antelle 136fbc2f77 updated macOS helper icon 2020-11-25 23:29:43 +01:00
antelle 25bc5643b1 removed app icon for macos 2020-11-25 23:21:29 +01:00
antelle a0c03363a7 removed an old favicon 2020-11-25 22:50:35 +01:00
antelle 8dd7a97769 removed a comment 2020-11-25 21:51:32 +01:00
antelle f70dfaaa28 icons adjustment 2020-11-25 21:40:54 +01:00
antelle 01ceb6dc37 replaced an icon 2020-11-25 21:07:07 +01:00
antelle d56e50b29d reverted the onedrive icon 2020-11-25 20:14:40 +01:00
antelle 0b2c722f61 replaced some icons 2020-11-25 20:10:37 +01:00
antelle 26990f38dd new pinned tab icon 2020-11-25 19:38:17 +01:00
antelle b2d87efc99 yubikey image 2020-11-25 18:28:26 +01:00
antelle 63b7b32e9c fontawesome 5 2020-11-25 18:20:53 +01:00
antelle 8925a48822 bugfix 2020-11-24 18:04:30 +01:00
antelle 8ad47181a9 removed an old edge hack 2020-11-24 17:54:04 +01:00
antelle c1b9ec7a77 icon 2020-11-23 23:39:04 +01:00
antelle 6daf34e261 new icon 2020-11-22 12:25:43 +01:00
antelle fc5c865b18 disabled contextIsolation 2020-11-20 20:46:01 +01:00
antelle 083306a1cd google-github-actions 2020-11-20 15:24:20 +01:00
antelle 5ebacbc347 building on node.js 15 2020-11-20 14:53:28 +01:00
antelle 08c4adfd46 fixed tests 2020-11-20 14:48:53 +01:00
antelle 27f87ad09f get-git-tag 2020-11-20 14:47:14 +01:00
antelle d0b33ca0c1 fix #1523: support for WebDAV servers without Last-Modified header 2020-11-20 14:08:13 +01:00
antelle bb44c7cb3e fixed some that=this 2020-11-20 13:12:06 +01:00
antelle 66e366d9d0 fix #1615: restoring the app window if it's activated when minimized 2020-11-20 10:29:47 +01:00
antelle 31390eac80 fix #1555: auto-saving files when minimize options is enabled 2020-11-19 23:37:09 +01:00
antelle 543a71f6f2 up deps 2020-11-19 18:43:50 +01:00
antelle 5d29b79dab bump electron 2020-11-19 16:52:27 +01:00
antelle 207ff77778 fix #1599: switched to Dropbox short-lived access tokens 2020-11-19 16:05:08 +01:00
antelle b85d25614b fix #1616: auto-type with no matching entries 2020-11-19 13:00:56 +01:00
antelle d1bcdca0d3 fix #1619: auto-locking ignored a field being edited 2020-11-19 11:21:45 +01:00
antelle ffb68b1651 fix #1561: error during loading configs after reset 2020-11-19 11:12:36 +01:00
antelle 49d46cfedc fixed YubiKey errors display 2020-11-11 23:08:08 +01:00
antelle 9c18e2877b fix #1589: shortcut to copy OTP 2020-11-11 19:01:12 +01:00
antelle a1da5ceabe fix #1608: improved the "Show all file" checkbox behavior 2020-11-11 18:44:57 +01:00
antelle 759b92bfd6 fixed a performance issue in searching entries 2020-11-10 23:19:26 +01:00
antelle b4f3d19259 Merge branch 'master' into develop 2020-11-09 21:35:57 +01:00
antelle 35e3271839 added a check for safety 2020-10-28 20:18:27 +01:00
antelle 90da86ebb8 fix #1621: colors on Linux 2020-10-28 20:17:13 +01:00
antelle ad978d2ed3 fix #1612: added WebCrypto check back 2020-10-02 18:07:46 +02:00
antelle 7140a2d894 npm i
Build / web (push) Canceled after 0s
Build / linux (push) Canceled after 0s
Build / darwin (push) Canceled after 0s
Build / win32 (push) Canceled after 0s
Build / publish (push) Canceled after 0s
2020-09-12 12:23:51 +02:00
antelle eb86603b47 Merge branch 'release-1.15' into master 2020-09-12 12:17:03 +02:00
antelle 1e1117c28b updated vulnerable dependencies 2020-09-12 12:16:41 +02:00
antelle f3de0d8391 Merge branch 'release-1.15' into master 2020-09-12 12:12:28 +02:00
antelle 4749be20b4 bump version 2020-09-12 12:10:15 +02:00
antelle 3eea00bf6d release notes 2020-09-12 12:06:38 +02:00
antelle d301287fdc readme 2020-09-12 12:05:45 +02:00
antelle 07f4090498 readme 2020-09-12 12:04:27 +02:00
antelle 067d3778d8 PKCE enabled on Dropbox 2020-09-12 12:04:16 +02:00
antelle daa250e8fa fix 1597: dropbox 2020-09-12 12:03:20 +02:00
antelle 91f992df39 up kdbxweb, fix #1591, fix #1598 2020-09-12 11:30:15 +02:00
antelle ecaf9a37da prettier 2020-09-09 21:42:37 +02:00
antelle 31cc2fbdd4 Merge branch 'opennomad-linux_auto_type' into release-1.15 2020-09-09 21:40:58 +02:00
Matthias Johnson 6e30687919 use windowactivate via xdotool 2020-09-08 12:31:33 -06:00
antelle dbf212f0df Merge branch 'master' into develop
# Conflicts:
#	release-notes.md
2020-08-08 14:29:11 +02:00
antelle af49645f8d Merge branch 'release-1.15'
Build / web (push) Canceled after 0s
Build / linux (push) Canceled after 0s
Build / darwin (push) Canceled after 0s
Build / win32 (push) Canceled after 0s
Build / publish (push) Canceled after 0s
2020-08-08 14:25:41 +02:00
antelle 59bed7593d fix #1581: double-clicking KeeWeb icon in Dock 2020-08-08 14:24:47 +02:00
antelle 43ca723c75 bump version 2020-08-08 14:23:42 +02:00
antelle 855370074f fix #1553: empty fields display for templates 2020-08-08 14:11:12 +02:00
antelle 84f707d6cd fix #1581: double-clicking KeeWeb icon in Dock 2020-08-08 12:20:08 +02:00
antelle 17be9cf266 removed some old stuff from v1.15 2020-06-21 13:04:09 +02:00
antelle 0e3d01ade6 always using native argon2 in desktop 2020-06-21 13:02:06 +02:00
antelle 02fe2b1754 Merge branch 'hesalx-fix-macos-quit' into release-1.15 2020-06-15 17:46:18 +02:00
hesalx a0c553b3a9 allow the app to quit when not minimized and window is closed 2020-06-15 11:32:48 +03:00
antelle 62ea631269 Merge branch 'release-1.15'
Build / web (push) Canceled after 0s
Build / linux (push) Canceled after 0s
Build / darwin (push) Canceled after 0s
Build / win32 (push) Canceled after 0s
Build / publish (push) Canceled after 0s
2020-06-13 19:30:36 +02:00
antelle b32d842394 bump version 2020-06-13 13:08:32 +02:00
antelle 0c38b5b9f1 fixed exe code signing 2020-06-13 13:08:16 +02:00
antelle dd0b20634c release notes 2020-06-13 13:08:09 +02:00
antelle f8319408f1 don't clear cache from the ci sandbox 2020-06-13 13:08:00 +02:00
antelle c451e92a9c fixed exe code signing 2020-06-13 12:31:48 +02:00
antelle 36cf70202d Merge branch 'master' into develop
# Conflicts:
#	desktop/app.js
#	release-notes.md
2020-06-13 12:30:48 +02:00
antelle 39fe83fdd1 Merge branch 'release-1.15'
Build / web (push) Canceled after 0s
Build / linux (push) Canceled after 0s
Build / darwin (push) Canceled after 0s
Build / win32 (push) Canceled after 0s
Build / publish (push) Canceled after 0s
2020-06-13 10:54:59 +02:00
antelle cc5a465dc3 up 2020-06-13 10:54:31 +02:00
antelle 2018f04bdf fixed exports 2020-06-13 10:54:10 +02:00
antelle f0e79eab95 Merge branch 'release-1.15' 2020-06-13 10:25:22 +02:00
antelle fc1b2fbbaa fix #1532: crashes on some Windows version (updated electron) 2020-06-13 08:49:59 +02:00
antelle a8e89da5e9 up deps 2020-06-13 08:48:37 +02:00
antelle e369a6b7be bump version 2020-06-12 21:15:58 +02:00
antelle ae4d4398cd fix #1536: added a missing dependency on linux 2020-06-12 21:15:36 +02:00
antelle 5781d20615 Merge branch 'release-1.15'
Build / web (push) Canceled after 0s
Build / linux (push) Canceled after 0s
Build / darwin (push) Canceled after 0s
Build / win32 (push) Canceled after 0s
Build / publish (push) Canceled after 0s
2020-06-11 19:54:52 +02:00
antelle a6e9521435 bump version 2020-06-11 19:53:53 +02:00
antelle 1e72711bc3 bump version script 2020-06-11 19:53:33 +02:00
antelle 1f793e2d00 bump version script 2020-06-11 19:53:21 +02:00
antelle af8d94d102 fix #1535: network errors in Dropbox and GDrive on Windows 2020-06-11 19:48:30 +02:00
antelle a424c3286a extracting files after signing 2020-06-10 20:27:55 +02:00
antelle 5f9b33506a Merge branch 'master' into release-1.15 2020-06-09 21:04:48 +02:00
antelle 819b10e1f6 fixed version
Build / web (push) Canceled after 0s
Build / linux (push) Canceled after 0s
Build / darwin (push) Canceled after 0s
Build / win32 (push) Canceled after 0s
Build / publish (push) Canceled after 0s
2020-06-09 21:02:08 +02:00
antelle 0c170766e5 Merge branch 'release-1.15' 2020-06-09 20:47:36 +02:00
antelle f7a0025b97 bump version 2020-06-09 20:47:07 +02:00
antelle 22776e9088 fix #1409: auto-type wrong character issues on Linux 2020-06-09 20:39:09 +02:00
antelle d23d393c39 - fixed duplicated YubiKeys displayed in file settings 2020-06-09 19:50:35 +02:00
antelle bbf6e796f8 updated electron version 2020-06-09 19:46:37 +02:00
antelle 1c3c194b3a possibility to debug startup with --start-logging 2020-06-09 19:36:18 +02:00
antelle 0cc633c5c1 added a possibility to log messages on startup 2020-06-09 19:35:17 +02:00
antelle 9a8f1ad508 fix #1530: running from directories with hash symbols 2020-06-09 19:26:59 +02:00
antelle 65f09c6535 fix #1530: running from directories with hash symbols 2020-06-09 19:26:41 +02:00
antelle d7db5d2c77 removed some debugging code 2020-06-09 19:09:37 +02:00
antelle 8205b01c65 added temporary debug logging 2020-06-08 22:58:11 +02:00
antelle d7ee936b27 fix #1530: recursive creation of the portable directory 2020-06-08 19:13:34 +02:00
antelle d9ae6f312f fix #1530: recursive creation of the portable directory 2020-06-08 19:12:59 +02:00
antelle aea9a513b4 removed a non-working link 2020-06-07 16:55:42 +02:00
antelle d3b65f6280 added a vimeo link 2020-06-07 13:53:15 +02:00
antelle 3bf53aa87f Merge branch 'master' into develop 2020-06-07 12:33:31 +02:00
antelle 5081df4f2f Merge branch 'master' into release-1.15 2020-06-07 12:33:10 +02:00
antelle b91dbdaa8f purging cloudflare cache after publishing a release 2020-06-07 12:32:22 +02:00
antelle c313de9f93 release date
Build / web (push) Canceled after 0s
Build / linux (push) Canceled after 0s
Build / darwin (push) Canceled after 0s
Build / win32 (push) Canceled after 0s
Build / publish (push) Canceled after 0s
2020-06-07 11:04:57 +02:00
antelle 09b00f3137 Merge branch 'release-1.15' 2020-06-07 11:03:39 +02:00
antelle 8342336e8d bump version 2020-06-07 09:48:23 +02:00
antelle fe245dc95e fix #1528: OTP generation for stored values 2020-06-07 09:47:36 +02:00
antelle 3001afd9db Merge branch 'develop'
Build / web (push) Canceled after 0s
Build / linux (push) Canceled after 0s
Build / darwin (push) Canceled after 0s
Build / win32 (push) Canceled after 0s
Build / publish (push) Canceled after 0s
2020-06-06 16:50:23 +02:00
antelle 48b5c8d4e7 up deps 2020-06-06 16:48:48 +02:00
antelle 21dc4e758f bump version 2020-06-06 16:47:32 +02:00
antelle 5c5fc0271e languages 2020-06-06 16:43:13 +02:00
antelle 082c6bee93 moved native modules to a native module host 2020-06-06 13:30:35 +02:00
antelle c1d354a6fb added an error when usb is disabled 2020-06-05 20:37:13 +02:00
antelle eab683ec71 removed all mentions of cordova
It never got enough love by contributors and it seems to be abandoned. Better to
implement this API in a separate repo.
2020-06-05 16:45:37 +02:00
antelle cd2b87b317 fixed refreshing the yubikey status 2020-06-05 16:41:54 +02:00
antelle 4abe63c00f fixed ykman path on macos 2020-06-05 16:41:38 +02:00
antelle 7e4e61e005 fixed ykman path on macos 2020-06-04 21:33:42 +02:00
antelle db38e015f8 option to skip code signing on macos 2020-06-04 20:13:15 +02:00
antelle ff20d2a554 up kdbxweb 2020-06-04 18:49:33 +02:00
antelle cb7df205bb up deps 2020-06-03 22:42:39 +02:00
antelle dfe2c42172 utils sh 2020-06-03 21:31:32 +02:00
antelle 4854c0c100 removed an unnecessary task 2020-06-03 21:28:31 +02:00
antelle 33bdf124c2 up languages 2020-06-03 21:27:17 +02:00
antelle 2d752ef144 fix #917: option to install without a desktop icon on Windows 2020-06-03 18:11:38 +02:00
antelle d258bce037 de 2020-06-03 11:31:40 +02:00
antelle 21ff37d82e workflow 2020-06-03 09:58:57 +02:00
antelle 312b08ca99 workflow 2020-06-03 09:58:39 +02:00
antelle a47f0d0ae5 up 2020-06-03 09:51:47 +02:00
antelle c1a6268c2d added some logging 2020-06-03 08:33:26 +02:00
antelle 65b6fe2e2e removed an old task 2020-06-02 22:30:21 +02:00
antelle 0f29e94272 default format for new files is now KDBX4 2020-06-02 21:57:41 +02:00
antelle dd9b6a1943 disabled codeql-analysis 2020-06-02 19:33:06 +02:00
antelle a45bc13248 override language detection 2020-06-02 19:26:59 +02:00
antelle b7b5caac9d trying out codeql-analysis 2020-06-02 19:22:27 +02:00
antelle 0eb5ebab0d wording 2020-06-02 19:14:48 +02:00
antelle f34b1011c8 more contributions 2020-06-02 17:48:09 +02:00
antelle 33049c21e7 contribution links 2020-06-02 17:39:03 +02:00
antelle 6c12822279 contribution links 2020-06-02 17:37:20 +02:00
antelle 8a3ff150a6 added contributions 2020-06-02 17:36:13 +02:00
antelle de4bfdf9e0 reformatted build.yaml 2020-06-02 14:16:06 +02:00
antelle 461a45dc51 packaging native dependencies separately 2020-06-02 13:58:25 +02:00
antelle 2b24d716a9 up deps 2020-06-02 13:00:17 +02:00
antelle 36b6fd80b8 added a comment to the workflow 2020-06-02 12:56:27 +02:00
antelle f8cbf51842 skipping code signing on windows 2020-06-02 12:43:05 +02:00
antelle 17fbf9188d option to skip code signing on Windows 2020-06-02 12:41:30 +02:00
antelle ec5bacd951 updated the workflow 2020-06-02 12:29:55 +02:00
antelle 56c8649040 up yk-api 2020-06-02 12:23:22 +02:00
antelle 435eb5779f fixed some portable installation issues on macos 2020-06-02 10:47:20 +02:00
antelle a83e04fe4d reverted config changes 2020-06-01 23:54:55 +02:00
antelle bdbff334a5 syntax for old node.js 2020-06-01 23:30:33 +02:00
antelle f70eb35f69 syntax for old node.js 2020-06-01 23:27:48 +02:00
antelle f1a5aba485 refactored codesignconfig 2020-06-01 22:54:38 +02:00
antelle f8e454dab3 splitted macos app signing and notarization 2020-06-01 22:51:42 +02:00
antelle 9988454af1 fixed app exit while the app is not ready 2020-06-01 16:59:32 +02:00
antelle e0b65bbebf up modules; prettier 2020-06-01 16:53:51 +02:00
antelle 09fd37820b bumped min electron version 2020-06-01 16:46:21 +02:00
antelle 360194c627 loading native modules from updated desktop archives 2020-06-01 16:45:18 +02:00
antelle 21768b1b59 testing builds 2020-06-01 15:55:52 +02:00
antelle 325d521f49 fix #448: minimized login option support on macOS 2020-06-01 15:02:19 +02:00
antelle 2deb241ff2 fix #830: minimize instead of close option on macOS 2020-06-01 14:42:06 +02:00
antelle a2194435e6 fix #1460: auto-type on double-clicking field labels 2020-06-01 10:25:16 +02:00
antelle 448e173f7e added a warning about Input Monitoring for mac 2020-06-01 07:30:00 +02:00
antelle 4b52280549 fixed sticky tips 2020-05-31 23:31:14 +02:00
antelle 9e09f7b7e7 fixed double yubikey alert when opening files from storages 2020-05-31 22:28:38 +02:00
antelle 83293d909e up 2020-05-31 20:26:48 +02:00
antelle 176553a674 fixed challenge-response calculation with padding 2020-05-31 16:35:36 +02:00
antelle a4b22b6c88 silenced the deprecation warning 2020-05-31 14:25:50 +02:00
antelle fb6bcdf5c9 added a possibility to refresh the list of yubikeys 2020-05-31 14:23:37 +02:00
antelle 776c75d823 grammar 2020-05-31 14:13:32 +02:00
antelle 143f7c6a7a yubikey enrollment 2020-05-31 14:13:08 +02:00
antelle b520c58ef4 cancelChalResp 2020-05-31 13:06:36 +02:00
antelle 3c47adbf32 fixed argon2 in browsers 2020-05-31 13:03:59 +02:00
antelle 835acff637 up 2020-05-31 13:00:35 +02:00
antelle a08e3c7d27 option to remember challenge-response codes 2020-05-31 10:15:27 +02:00
antelle d9258745d0 fixed file saving errors 2020-05-30 23:28:33 +02:00
antelle 70bd4f1c4e fixed main window close/closed events confusion 2020-05-30 17:46:13 +02:00
antelle ab3860cdc9 fixed errors during auto-save 2020-05-30 17:40:18 +02:00
antelle 9185ef9a55 showing main window for yubikey alerts 2020-05-30 17:12:48 +02:00
antelle e6826b176e yubikey ui alerts 2020-05-30 16:02:02 +02:00
antelle f5bb29e61a fixed open args 2020-05-30 14:28:06 +02:00
antelle d0d013e046 clearing cache on file close 2020-05-30 12:45:56 +02:00
antelle 5002c2ce67 better building instructions 2020-05-30 12:06:53 +02:00
antelle 8e3b218a74 readme 2020-05-30 12:02:04 +02:00
antelle 51bd80faf4 fixed saved yubikeys 2020-05-30 10:29:02 +02:00
antelle b4fe0af53a extracted challenge-response calculator 2020-05-30 08:19:47 +02:00
antelle 2ba9a03e2c using yubikeys for opening files 2020-05-30 08:10:19 +02:00
antelle 7394754b6f fixed an error when files were closed during sync 2020-05-30 07:47:52 +02:00
antelle b41b291e60 added desktop module description 2020-05-30 07:39:31 +02:00
antelle 0f582e3248 refreshing the list of yubikeys on the start screen 2020-05-29 23:24:05 +02:00
antelle b90e84be42 loading yubikeys using a native module 2020-05-29 23:15:10 +02:00
antelle ef627c9530 updated keeweb-native-modules 2020-05-29 21:49:33 +02:00
antelle b3f021a577 fixed eslint 2020-05-28 18:34:32 +02:00
antelle 96263c11ec escaping more characters in xml, see #1520 2020-05-28 10:54:52 +02:00
antelle b2a6e1180c reverted renderer process native modules, it crashes 2020-05-28 10:48:09 +02:00
antelle 817b44b152 fixed an error during loading the list of yubikeys 2020-05-26 23:26:26 +02:00
antelle 701bb4caa4 loading compatible modules in renderer process 2020-05-26 23:24:00 +02:00
antelle a1b8682316 moved the stuck yubikey flag to the otp section 2020-05-25 19:40:04 +02:00
antelle 8c386dbe57 challenge-response calculation function 2020-05-24 21:06:53 +02:00
antelle d8e49d993a added a text about used yubikey 2020-05-24 20:31:03 +02:00
antelle 93310eb029 listing YubiKeys on the open view 2020-05-24 20:02:49 +02:00
antelle f215c26a63 removed plugin cache invalidation with timestamps 2020-05-24 19:07:01 +02:00
antelle b5fddeb627 added a missing check 2020-05-24 18:42:14 +02:00
antelle 81d4c5c403 extracted YubiKey module 2020-05-24 18:39:56 +02:00
antelle bf7dec2437 fixed writing unencrypted configs 2020-05-24 13:46:03 +02:00
antelle efa9b5f9a7 fixed the yubikey challenge-response icon on the open screen 2020-05-23 19:26:54 +02:00
antelle 1f862a37e9 fixed yubikey icon on the open screen 2020-05-23 19:07:45 +02:00
antelle e8a491dba5 disabled sandbox mode in package.json/electron 2020-05-23 17:08:55 +02:00
antelle aa899b8096 fix #1409: fixed auto-typing Tab character on Debian 2020-05-23 17:07:59 +02:00
antelle 8de55c450a fixed sticky tooltips in settings 2020-05-22 22:44:50 +02:00
antelle 1fafa68793 restructured settings code a bit 2020-05-22 22:28:12 +02:00
antelle e69219697a serializing settings in renderer 2020-05-22 22:17:36 +02:00
Dimitri Witkowski 08a0f6e587 Merge pull request #1514 from b3nj5m1n/add_check_support_windowid
Added check for system supporting window id
2020-05-22 21:48:06 +02:00
b3nj5m1n 7a26d80255 Removed log from debugging 2020-05-22 21:10:52 +02:00
b3nj4m1n 4171848655 Added check for system supporting window id 2020-05-22 21:05:30 +02:00
antelle a7193fd783 fixed config writing 2020-05-22 20:55:05 +02:00
antelle ccce95d4fe fixed configs for portable installations 2020-05-22 20:54:47 +02:00
antelle b9f37c22d9 config encryption with a key from keychain 2020-05-22 20:46:03 +02:00
Dimitri Witkowski 3b3c95e57c Merge pull request #1513 from b3nj5m1n/fix_app_dock
Added check for platform before calling app.dock
2020-05-22 18:58:50 +02:00
b3nj4m1n fadea36232 Added check for platform before calling app.dock 2020-05-22 18:47:26 +02:00
antelle 99b687244c release notes: fix #1509: fixed auto-type for tiling mode in Linux 2020-05-22 12:34:31 +02:00
antelle 813b26270f extracted a constant 2020-05-22 12:30:01 +02:00
antelle b715507dd0 Merge branch 'b3nj5m1n-autotype-tilingwm' into develop 2020-05-22 12:25:11 +02:00
b3nj4m1n 0cb502ca67 Fixed possible error for undefined window id 2020-05-22 12:10:27 +02:00
antelle e5073eb65f default theme on macOS 2020-05-22 11:44:49 +02:00
antelle c3b55cd7fa better portable app checks 2020-05-22 10:56:08 +02:00
antelle e9ef1bd698 fixed remote events 2020-05-22 10:44:59 +02:00
antelle 045fe99158 made dropbox secret hidden 2020-05-22 10:15:21 +02:00
antelle dad95033c0 added a possibility to clear a storage provider field in app settings 2020-05-22 10:14:43 +02:00
b3nj4m1n 02e4d52db6 windowId gets passed in a different place 2020-05-21 21:36:26 +02:00
b3nj4m1n 1f83f34e55 Addressed requested changes 2020-05-21 19:41:19 +02:00
b3nj4m1n 1ffb45433c Fixed auto-type on tiling wm 2020-05-21 17:10:32 +02:00
antelle b6780dff03 ignored tags for yubikey entries 2020-05-16 10:03:02 +02:00
antelle 5b91dcb272 fix #1440: fixed auto-type for maximized windows 2020-05-15 22:41:39 +02:00
antelle 099f1ca9d0 calling openDevTools from window.webContents 2020-05-15 21:54:34 +02:00
antelle c73f81a80a dev desktop tasks 2020-05-15 21:38:33 +02:00
antelle 177b150c95 Merge branch 'master' into develop
# Conflicts:
#	app/templates/export/entry.hbs
#	release-notes.md
2020-05-15 20:52:16 +02:00
antelle 489eb5598c Merge branch 'release-1.14'
Build / web (push) Canceled after 0s
Build / linux (push) Canceled after 0s
Build / darwin (push) Canceled after 0s
Build / win32 (push) Canceled after 0s
Build / publish (push) Canceled after 0s
2020-05-15 20:37:24 +02:00
antelle ad571c1e27 fix eslint 2020-05-15 20:36:59 +02:00
antelle 9827b871fc Merge branch 'release-1.14' 2020-05-15 20:26:25 +02:00
antelle 004436e868 bump version 2020-05-15 20:25:57 +02:00
antelle 008b615903 improved exporting files with markdown notes 2020-05-15 20:25:22 +02:00
antelle 451b465e4f disabled markdown in export 2020-05-15 20:17:40 +02:00
antelle c91e5de961 readme formatting 2020-05-15 20:14:55 +02:00
antelle 8251423d95 up deps 2020-05-15 20:00:18 +02:00
antelle 65f66ac60c fix #1503: arm64 Windows installer 2020-05-14 22:59:11 +02:00
antelle 94caa1fca3 fix #1503: building windows arm64 2020-05-14 20:52:02 +02:00
antelle f7d1708550 removed pcsclite 2020-05-14 20:47:11 +02:00
antelle b888f9da32 ignored unnecessary native modules 2020-05-14 20:36:14 +02:00
antelle 4d678184f3 option to create a portable installation 2020-05-14 20:11:41 +02:00
antelle a2bf157b01 fixed portable executable dir 2020-05-14 18:55:11 +02:00
antelle 1b279119cb auto-opening yubikeys with other files 2020-05-14 18:31:26 +02:00
antelle 2075e82381 increased the yubikey reconnect timeout 2020-05-13 22:29:12 +02:00
antelle 9f60ca8ece fix #1506: replaced incorrectly added client secret config properties 2020-05-13 22:25:33 +02:00
antelle d6867fb62e added native modules links 2020-05-13 21:25:43 +02:00
antelle 07e918965b fix #620: clearing middle-click clipboard in Linux 2020-05-13 21:20:26 +02:00
antelle 24bcc758e7 release notes 2020-05-13 20:26:25 +02:00
antelle 7ae64b0552 fixed native argon2 2020-05-13 20:25:45 +02:00
antelle 38e46f6d85 building native modules into asar 2020-05-13 20:25:33 +02:00
antelle 530316c25f native modules for all available architectures 2020-05-13 19:15:56 +02:00
antelle cc750df077 moved native modules to the main process 2020-05-13 17:44:33 +02:00
antelle 3c85694fc2 removed temp paths from profile 2020-05-13 17:03:23 +02:00
antelle 955a1346ff removed old cookie handling 2020-05-13 16:37:35 +02:00
antelle 8e4566fe5f moved app options 2020-05-12 23:46:19 +02:00
antelle 20623e4c42 disabled unnecessary caching 2020-05-12 23:10:26 +02:00
antelle cac31d3350 added a yubikey selection icon to the open screen 2020-05-11 19:29:39 +02:00
antelle 746b56ac57 release notes 2020-05-11 19:11:14 +02:00
antelle bc140b3fb5 auto-opening yubikeys 2020-05-11 18:49:21 +02:00
antelle 5d15411d3d fixed sequential otp generation 2020-05-11 17:44:18 +02:00
antelle c6ce694dfe displaying matching otp codes in entries 2020-05-11 17:24:06 +02:00
antelle 16d303d966 fixed password field after idle period 2020-05-10 19:44:29 +02:00
antelle f422dbd3db fixed variable name 2020-05-10 16:48:58 +02:00
antelle 5125a44170 added enter to the default totp command 2020-05-10 11:42:13 +02:00
antelle 6e7f2c570f fixed dev app icon 2020-05-10 09:49:09 +02:00
antelle db31e65cdf fixed entry creation on a yubikey 2020-05-09 23:55:57 +02:00
antelle 3cd9bf6505 html => empty 2020-05-09 20:15:46 +02:00
antelle 3b05f6267e escaping fields autocomplete 2020-05-09 17:00:39 +02:00
antelle 3e5b0bff4f renamed content to contentHtml 2020-05-09 16:39:04 +02:00
antelle c9cb15d7b7 removed shortcuts formatting 2020-05-09 16:35:11 +02:00
antelle 89415c86a4 escaping details shortcuts 2020-05-09 16:18:39 +02:00
antelle 4cd515b19f put export csp back 2020-05-09 16:16:27 +02:00
antelle 730e2c5ba5 removed export csp 2020-05-09 16:14:56 +02:00
antelle 3735a6689c escaping attachments 2020-05-09 16:14:43 +02:00
antelle 15c81d8f35 partials support 2020-05-09 16:14:20 +02:00
antelle 154c780281 disabled markdown in export 2020-05-09 15:25:11 +02:00
antelle ec9422d22d added csp for exported html 2020-05-09 14:39:18 +02:00
antelle 101e8eaa24 fixed sort options 2020-05-09 10:59:23 +02:00
antelle 6a31bba69c using optional chaining 2020-05-09 10:45:12 +02:00
antelle 96ee68dee7 fixed yubikey totp auto-type 2020-05-09 10:37:34 +02:00
antelle 5a94c81b11 fixed yubikey username auto-type 2020-05-09 08:57:57 +02:00
antelle cf8aa6f9a4 copying otp from yubikeys 2020-05-08 23:33:57 +02:00
antelle 20e201795e options for yubikey username field 2020-05-08 23:16:13 +02:00
antelle e95902d2bb wording: one-time codes 2020-05-08 23:15:38 +02:00
antelle 79a3b39248 disabled KEEWEB_HTML_PATH in prod builds 2020-05-08 16:20:23 +02:00
antelle c08a0eb8d1 fixed the details view 2020-05-07 23:10:35 +02:00
antelle a280258d4f cleaned up openProcess 2020-05-07 23:10:23 +02:00
antelle 7985a7a522 added a better message when a yubikey is stuck 2020-05-07 22:07:58 +02:00
antelle 6ba2e16a91 fixed yubikey reconnection 2020-05-07 21:22:34 +02:00
antelle f34ebe2fd3 code cleanup 2020-05-07 19:00:18 +02:00
antelle ab3d4a056f fixed the yubikey workaround 2020-05-07 18:58:17 +02:00
antelle c88a7c000b extracted a method 2020-05-06 23:12:49 +02:00
antelle 53b700aa70 fixed yubikey serial detection 2020-05-06 23:06:22 +02:00
antelle 66c219f6d1 locale 2020-05-06 21:08:37 +02:00
antelle 06dd153955 fixed stuck yubikeys 2020-05-06 21:06:19 +02:00
antelle 88a0e63894 disabled auto-open by default 2020-05-06 19:49:21 +02:00
antelle cac7e53ea8 fixed work with several yubikeys 2020-05-06 19:30:30 +02:00
antelle 3e390388eb removed a workaround for Edge 2020-05-06 18:44:00 +02:00
antelle 2a1b01c0aa displaying last open file after detaching a yubikey 2020-05-06 18:43:04 +02:00
antelle 5a535bb07a Added a yubikey workaround 2020-05-06 18:37:37 +02:00
antelle 235ceae228 restarting the yubikey application if it's stuck 2020-05-05 22:36:23 +02:00
antelle 46710aead4 watching yubikeys 2020-05-05 21:26:41 +02:00
antelle 277d443d4c Merge branch 'usb' into develop 2020-05-05 20:58:20 +02:00
antelle 770c25a273 fixed open files 2020-05-05 20:57:26 +02:00
antelle c935de3ec1 message 2020-05-05 20:51:01 +02:00
antelle 8350123839 devices 2020-05-05 20:50:11 +02:00
antelle 02adb81ae0 settings 2020-05-05 20:47:15 +02:00
antelle cf26427e68 fix otp cancel 2020-05-05 20:14:32 +02:00
antelle 6e357e93ec props 2020-05-05 20:03:38 +02:00
antelle 1c8f3932fb search fix 2020-05-05 18:11:58 +02:00
antelle 75671a0a8a canUseNativeModules 2020-05-05 18:01:16 +02:00
antelle 58296dd896 disabled yubikey on win32 2020-05-05 17:57:01 +02:00
antelle 2fff34dc61 grammar 2020-05-05 17:49:19 +02:00
antelle 851ade7e24 fixed drag 2020-05-05 17:46:07 +02:00
antelle 13585f5317 splitted detail fields 2020-05-05 17:28:20 +02:00
antelle 5d0ab36f2c fixed details 2020-05-05 17:05:20 +02:00
antelle be46cf9a25 lint fix 2020-05-05 16:37:25 +02:00
antelle ffdc438091 removed app-model prepare 2020-05-05 16:34:39 +02:00
antelle 52741cf46a search tests 2020-05-05 16:23:17 +02:00
antelle 9263caed59 search 2020-05-05 15:08:19 +02:00
antelle aa5a9fc6d2 Merge branch 'master' into usb
# Conflicts:
#	app/scripts/app.js
#	package.json
#	release-notes.md
2020-05-04 19:46:07 +02:00
antelle 316518d63b Merge branch 'master' into develop
# Conflicts:
#	package.json
#	release-notes.md
2020-05-04 19:45:03 +02:00
antelle 03c44d76c9 Merge branch 'release-1.14'
Build / web (push) Canceled after 0s
Build / linux (push) Canceled after 0s
Build / darwin (push) Canceled after 0s
Build / win32 (push) Canceled after 0s
Build / publish (push) Canceled after 0s
2020-05-04 19:21:54 +02:00
antelle 346d6cb119 fixed dist html file location 2020-05-04 19:21:29 +02:00
antelle dae3d57d1e Merge branch 'release-1.14' 2020-05-04 19:12:47 +02:00
antelle aa65cef103 bump version 2020-05-04 19:12:08 +02:00
antelle e19c923538 up deps 2020-05-04 19:11:20 +02:00
antelle ec292705b3 distinct redirect URIs for storage providers 2020-05-04 19:06:05 +02:00
antelle d36588d148 ignored the whole file in prettier 2020-05-02 19:54:47 +02:00
antelle 32c171d05b Merge branch 'develop' into usb 2020-05-02 14:05:47 +02:00
antelle f031be4ce2 Merge branch 'master' into develop
# Conflicts:
#	app/scripts/storage/storage-base.js
#	release-notes.md
2020-05-02 14:04:53 +02:00
antelle d3ebcabec4 Merge branch 'master' into release-1.14 2020-05-02 14:03:04 +02:00
antelle f683f14a30 up gh-actions
Build / web (push) Canceled after 0s
Build / linux (push) Canceled after 0s
Build / darwin (push) Canceled after 0s
Build / win32 (push) Canceled after 0s
Build / publish (push) Canceled after 0s
2020-05-02 13:40:03 +02:00
antelle 0a311e87e4 up gh-actions 2020-05-02 13:39:42 +02:00
antelle d42ce3e7bb npm audit 2020-05-02 13:36:09 +02:00
antelle 4c5d7eb762 Merge branch 'release-1.14' 2020-05-02 13:31:26 +02:00
antelle 1d58779d90 bump version 2020-05-02 13:30:24 +02:00
antelle 1434d81d3e bump version 2020-05-02 13:30:10 +02:00
antelle b44d060fac languages 2020-05-02 13:29:05 +02:00
antelle 7c89ebc047 fixed a typo 2020-05-01 18:37:27 +02:00
antelle d140427c94 fix #1478: fixed proxy issues with storage providers 2020-04-30 17:59:22 +02:00
antelle 2abdf3693c Merge branch 'master' into release-1.14 2020-04-30 16:33:18 +02:00
antelle 8d1eafe2bc Merge branch 'develop' into usb 2020-04-29 19:24:47 +02:00
antelle 510f982579 Merge branch 'master' into develop 2020-04-29 18:59:43 +02:00
antelle 63e6be9867 plugin ids 2020-04-29 18:48:39 +02:00
antelle 0a2957449f added blob: to script-src 2020-04-29 18:41:50 +02:00
antelle ee2ba047ab removed eval's 2020-04-29 18:41:16 +02:00
antelle a8590c1b90 icon 2020-04-29 18:17:26 +02:00
Dimitri Witkowski 374f4bc116 Create SECURITY.md 2020-04-28 23:33:23 +02:00
antelle 76fa1f6c9f merge 2020-04-23 20:50:53 +02:00
antelle dd68aa342a Merge branch 'develop' into usb
# Conflicts:
#	app/scripts/const/default-app-settings.js
#	app/scripts/views/open-view.js
2020-04-23 20:26:52 +02:00
antelle 21d614aa97 escaping dangerous places 2020-04-23 20:09:37 +02:00
antelle f4e4bbbb8f escaping dangerous places 2020-04-23 20:06:10 +02:00
antelle d30c9d9d90 escaping more dangerous places 2020-04-23 19:55:52 +02:00
antelle e0884a4eec escaping dangerous places 2020-04-23 19:24:39 +02:00
antelle 446c7f3ab5 fixed webdav pattern 2020-04-23 19:17:05 +02:00
antelle 48a6189fe7 dropdown hint option 2020-04-23 19:12:15 +02:00
antelle e568d06b02 fix #1350: clearing master password after auto lock period 2020-04-23 18:47:46 +02:00
antelle 243c962667 #1471: WebDAV url validation 2020-04-23 18:39:59 +02:00
antelle 908510ff0b fix #1342: hint that the data will be stored in unencrypted form after exporting 2020-04-23 18:36:26 +02:00
antelle d6aab0c470 fix #1463: copying the original url instead of adding https: 2020-04-23 18:30:17 +02:00
antelle 8d2640d99d fix #1400: auto-apply tag when creating new entry in tag view 2020-04-23 18:20:46 +02:00
antelle d45748cc32 fix #557, fix #513: Argon2 speed improvements in desktop apps 2020-04-23 18:12:16 +02:00
antelle 2693dd9366 more network logging
(cherry picked from commit 92fb322f7b)
2020-04-21 16:35:20 +02:00
antelle dcfa070176 translated a dropbox message
(cherry picked from commit abc154738c)
2020-04-21 16:34:22 +02:00
antelle eb577d61d5 fix 2020-04-19 20:55:38 +02:00
antelle f79bb90b69 tooling check 2020-04-19 20:42:55 +02:00
antelle 4591268063 settings 2020-04-19 18:52:21 +02:00
antelle 7e849934ff Merge branch 'develop' into usb 2020-04-19 16:11:11 +02:00
antelle 92fb322f7b more network logging 2020-04-18 15:48:47 +02:00
antelle abc154738c translated a dropbox message 2020-04-18 15:48:29 +02:00
antelle 63850f75af Merge branch 'master' into develop 2020-04-18 15:23:40 +02:00
antelle e0498e5e87 contributing 2020-04-18 13:11:05 +02:00
antelle 232f0b8d69 issue template 2020-04-18 13:08:43 +02:00
antelle d410dbb17d issue template 2020-04-18 13:06:04 +02:00
antelle e7c3d0441c issue template 2020-04-18 13:04:27 +02:00
antelle 0119d69641 readme 2020-04-18 13:00:21 +02:00
antelle a21fdf50bb contributing 2020-04-18 12:59:09 +02:00
antelle 8fdc5e6d94 contributing 2020-04-18 12:56:18 +02:00
antelle 41e81c2d7a contributing 2020-04-18 12:53:30 +02:00
antelle 10d2f5e641 contributing 2020-04-18 12:53:05 +02:00
antelle cdfcc6493c contributing 2020-04-18 12:48:57 +02:00
antelle 6b26f6d93f contributing 2020-04-18 12:48:26 +02:00
antelle a11cf38378 contributing 2020-04-18 12:47:28 +02:00
antelle 7d061c4aaf contributing 2020-04-18 12:47:00 +02:00
antelle 152fcccf60 contributing 2020-04-18 12:40:10 +02:00
antelle 159104a50a merge 2020-04-18 11:04:06 +02:00
antelle 66b2b77791 Merge branch 'develop' into usb
# Conflicts:
#	app/scripts/models/app-settings-model.js
#	desktop/app.js
2020-04-18 11:03:06 +02:00
antelle 36ade29e46 Merge branch 'master' into develop 2020-04-18 10:52:41 +02:00
antelle 61c44057cb Merge branch 'release-1.14' 2020-04-18 10:52:07 +02:00
antelle fd9dc1a801 github action rebuilt 2020-04-18 10:51:29 +02:00
antelle 57b813196f Merge branch 'release-1.14' into develop 2020-04-18 09:04:49 +02:00
antelle eaf429de3d downgraded a dependency dut to failing ci
Build / win32 (push) Canceled after 0s
Build / publish (push) Canceled after 0s
Build / web (push) Canceled after 0s
Build / linux (push) Canceled after 0s
Build / darwin (push) Canceled after 0s
2020-04-18 08:40:33 +02:00
antelle 45923d034e Merge branch 'develop' 2020-04-18 08:30:17 +02:00
antelle fbdfacd14d saving only modified settings instead of everything 2020-04-18 08:28:56 +02:00
antelle a55ddda6cf release notes 2020-04-18 08:05:57 +02:00
antelle 6c66d0791a deps 2020-04-18 08:05:12 +02:00
antelle c19d427f3a bump version 2020-04-17 23:28:21 +02:00
antelle a078081347 bump version 2020-04-17 22:25:52 +02:00
antelle 3a042f25c2 disabled navigation in desktop 2020-04-17 21:54:34 +02:00
antelle 6d781a6358 disabled creation of new windows 2020-04-17 21:50:53 +02:00
antelle 349ec59df7 option to log out from storages 2020-04-17 21:36:56 +02:00
antelle 833aa3c748 canOpenWebdav is now canOpenStorage 2020-04-17 20:58:47 +02:00
antelle eca5b1c7a0 moved CSP a bit closer to the beginning of the html 2020-04-17 20:56:23 +02:00
antelle 0aa925f95d checking origin in window message handlers 2020-04-17 20:53:40 +02:00
antelle 2f214b25c7 filtering protocols in the url field 2020-04-17 20:45:41 +02:00
antelle 38c3a46395 escaping html in dropdowns 2020-04-17 20:28:03 +02:00
antelle cbb9a29c8d escaping html in tooltips 2020-04-17 20:06:30 +02:00
antelle dddc4f235e escaping html in the notes field 2020-04-17 19:58:17 +02:00
antelle c537d0f464 using OAuth authorization code grant for all storage providers 2020-04-17 19:42:35 +02:00
antelle 8be588afdf Merge branch 'develop' into usb 2020-04-15 19:52:54 +02:00
antelle 5b6c707de5 Merge branch 'master' into develop 2020-04-15 19:52:29 +02:00
antelle 8b6dd322a7 release notes template 2020-04-15 19:51:42 +02:00
antelle dfdbd8b092 devtools fix 2020-04-15 19:37:03 +02:00
antelle 4fad58b1e9 Merge branch 'develop' into usb
# Conflicts:
#	app/scripts/models/app-settings-model.js
#	app/templates/open.hbs
2020-04-15 18:23:52 +02:00
antelle 6003b21f6a Merge branch 'master' into develop 2020-04-15 18:22:41 +02:00
antelle 963f09057c Merge branch 'release-1.13'
Build / web (push) Canceled after 0s
Build / linux (push) Canceled after 0s
Build / darwin (push) Canceled after 0s
Build / win32 (push) Canceled after 0s
Build / publish (push) Canceled after 0s
2020-04-15 17:52:15 +02:00
antelle b185c3e102 bump version 2020-04-15 17:29:56 +02:00
antelle 272365dde7 up languages 2020-04-15 17:28:51 +02:00
antelle da91254cf0 #1456: options to hide webdav and password generator 2020-04-15 17:26:10 +02:00
antelle 70642b464e fix #1457: fixed styles in theme plugins 2020-04-15 17:12:02 +02:00
antelle 035a4485b7 usb 101 2020-04-15 16:50:01 +02:00
antelle 73ac7496e2 Merge branch 'master' into develop 2020-04-11 18:29:15 +02:00
antelle 40d816f86d Merge remote-tracking branch 'remotes/origin/release-1.13'
Build / web (push) Canceled after 0s
Build / linux (push) Canceled after 0s
Build / darwin (push) Canceled after 0s
Build / win32 (push) Canceled after 0s
Build / publish (push) Canceled after 0s
2020-04-11 18:25:40 +02:00
antelle c513fb06e7 bump version 2020-04-11 18:24:46 +02:00
antelle dec0b4d171 fix #1451: fixed slow global auto-type on desktop 2020-04-11 18:24:23 +02:00
antelle 03ed25f617 Merge branch 'master' into develop 2020-04-11 17:14:59 +02:00
antelle 487afe799e up deps 2020-04-10 19:53:19 +02:00
antelle d15366ee24 copying 404 to dist 2020-04-09 18:38:27 +02:00
antelle 816c7776f7 copying 404 to dist 2020-04-09 18:36:56 +02:00
antelle f5eadc5d9e Merge branch 'release-1.13'
Build / web (push) Canceled after 0s
Build / linux (push) Canceled after 0s
Build / darwin (push) Canceled after 0s
Build / win32 (push) Canceled after 0s
Build / publish (push) Canceled after 0s
2020-04-09 07:22:35 +02:00
antelle 8e02c0bd10 bump version 2020-04-09 07:21:08 +02:00
antelle 614f61ce29 Merge branch 'develop' 2020-04-09 07:18:27 +02:00
antelle 6c80d50290 deleted GCP_SA_EMAIL 2020-04-08 23:37:21 +02:00
antelle 5492e53ba9 fix #1443: CI 2020-04-08 23:32:32 +02:00
antelle e795a317cc fixed docker build 2020-04-08 20:23:45 +02:00
antelle 8eb7366a4e finish-release task 2020-04-08 08:02:59 +02:00
antelle b85eab9d10 fix app name 2020-04-07 22:49:19 +02:00
antelle 09b0920337 release notes publishing: bin 2020-04-07 20:21:34 +02:00
antelle 502860ac5e release notes publishing 2020-04-07 20:17:56 +02:00
antelle 68d845ff3d fixed Docker build 2020-04-07 17:12:53 +02:00
antelle b2e69b60a6 files previously created as v4.1 will be written as v4.0 2020-04-07 17:07:05 +02:00
antelle 8015da09e8 debugging publish 2020-04-06 21:56:27 +02:00
antelle 06ed20f59c debugging publish 2020-04-06 21:51:54 +02:00
antelle a003d8bfe6 fixed release file path 2020-04-06 21:48:32 +02:00
antelle 468aa28449 publish release action 2020-04-06 21:41:44 +02:00
antelle e0615c751e ci 2020-04-05 23:39:36 +02:00
antelle 81e4a0eff9 ci 2020-04-05 23:29:34 +02:00
antelle b48ece91b2 ci 2020-04-05 23:21:39 +02:00
antelle 912d2b1e0a signtool 2020-04-05 22:45:46 +02:00
antelle c97f45e3e5 exlint 2020-04-05 22:15:35 +02:00
antelle de4230e0d0 code signing 2020-04-05 22:13:06 +02:00
antelle 79ca627e7c remote code signing 2020-04-05 21:43:32 +02:00
antelle 52045ad2a6 removed an old comment 2020-04-04 22:55:12 +02:00
antelle a6a9554868 Merge branch 'master' into develop 2020-04-04 22:54:23 +02:00
antelle d92229095d bump version 2020-04-04 21:53:02 +02:00
antelle 1d1ce0c322 Merge branch 'release-1.13' 2020-04-04 21:42:05 +02:00
antelle cb45eb4b3c Merge branch 'master' into release-1.13
# Conflicts:
#	Gruntfile.js
2020-04-04 21:41:29 +02:00
antelle 0b31150a43 Merge branch 'develop' 2020-04-04 21:39:40 +02:00
antelle b626152fda desktop-win32 2020-04-04 21:15:07 +02:00
antelle 3cc2cedaa5 codesign path 2020-04-04 20:27:43 +02:00
antelle e2fb54f88d desktop-darwin 2020-04-04 20:07:26 +02:00
antelle 1f334ab3dc ci 2020-04-04 19:53:18 +02:00
antelle c39933c051 fix #1447: fixed opening databases from Dock 2020-04-04 19:46:19 +02:00
antelle b6719e8972 promise 2020-04-04 19:43:12 +02:00
antelle cfaa765858 building desktop apps on ci 2020-04-04 19:26:27 +02:00
antelle 8477df7e5c build folder 2020-04-04 18:04:42 +02:00
antelle 40f3ccc112 fix deploy 2020-04-04 18:02:51 +02:00
antelle a40c116617 linux build action 2020-04-04 18:02:32 +02:00
antelle c97219311f dist name 2020-04-04 17:12:01 +02:00
antelle 49d618f066 disabled publish 2020-04-04 17:00:07 +02:00
antelle 129a77ae7c disabled publish 2020-04-04 16:36:24 +02:00
antelle b2d13db01f disabled publish 2020-04-04 16:27:19 +02:00
antelle c76cebc469 desktop-linux 2020-04-04 10:52:53 +02:00
antelle 668bb9b5d5 removed --no-sign 2020-04-04 10:25:12 +02:00
antelle ec82af7a68 fixed codesign config error 2020-04-04 10:07:10 +02:00
antelle 73b7880d73 fixed codesign config error 2020-04-04 09:55:11 +02:00
antelle a584eecb70 a developer => the developer 2020-04-03 22:47:14 +02:00
antelle cd0a25f910 fix #1445: fixed offline mode in Chrome and Firefox 2020-04-03 22:44:08 +02:00
antelle 6cf2bf109c fix #1444: fixed website favicons and attached images 2020-04-03 22:30:20 +02:00
antelle f6b7c7bb00 Merge branch 'develop' 2020-04-03 21:09:32 +02:00
antelle e987970969 languages 2020-04-03 21:08:02 +02:00
antelle 18d8037309 bump version 2020-04-03 20:28:48 +02:00
antelle 4c1dda68b5 signing code on a Windows VM 2020-04-03 20:26:27 +02:00
antelle 086f2c73db checking links being opened 2020-04-03 18:25:26 +02:00
antelle f7eab86166 removed insecure options from popups, see #1437 2020-04-03 18:17:44 +02:00
antelle 05b2b395ad preventing navigation in the main window 2020-04-03 18:06:14 +02:00
antelle c5298242f6 fixed appimage 2020-04-03 17:17:30 +02:00
antelle 37914d3cb5 allow key rotation in updated plugins 2020-04-02 16:47:50 +02:00
antelle 280ed45199 fix #1438: content security policy 2020-04-02 16:27:10 +02:00
antelle ea20740581 downgraded prettier 2020-03-31 22:00:56 +02:00
antelle 3b7d28130b up deps 2020-03-31 19:30:50 +02:00
antelle 72503916a1 svg icons 2020-03-29 15:01:11 +02:00
antelle cb150bdba9 fetching time 2020-03-29 11:11:16 +02:00
antelle 7c16a79629 fix profiling 2020-03-29 11:06:05 +02:00
antelle 1f5cd55272 app startup time profiling 2020-03-29 10:59:40 +02:00
antelle 7f4a7f05f5 displaying fetch time 2020-03-29 09:55:17 +02:00
antelle 95239fb257 start profiler 2020-03-29 09:23:49 +02:00
antelle f2583bc37f renamed the variable to KEEWEB_PORTABLE_EXECUTABLE_DIR, see #1065 2020-03-24 17:07:30 +01:00
antelle 00d7ff6604 favicon service url 2020-03-24 07:55:28 +01:00
antelle 5011c3ba04 deploy 2020-03-23 21:46:02 +01:00
antelle 9baa446675 removed tools 2020-03-23 21:33:11 +01:00
antelle 9e7f86e4d6 cloning keeweb-site from master 2020-03-23 18:36:20 +01:00
antelle 5ac4b42452 logging storage requests 2020-03-22 20:58:29 +01:00
antelle e9b05fe345 release notes 2020-03-22 07:55:16 +01:00
antelle 13ac013e9f input position 2020-03-21 17:46:39 +01:00
antelle d3b635ffd6 eslint 2020-03-21 17:39:36 +01:00
antelle e09609cc68 input width 2020-03-21 17:38:34 +01:00
antelle d2f64630f5 input width 2020-03-21 16:53:44 +01:00
antelle 0c3d8b77e4 grammar 2020-03-21 16:49:25 +01:00
antelle 905d09899c fix #1295, fix #1353: displaying passwords as protected fields regardless of settings in the file 2020-03-21 15:54:12 +01:00
antelle 0712c9f24b moved tests 2020-03-21 12:43:59 +01:00
antelle 29329f924e password presenter test 2020-03-21 12:24:21 +01:00
antelle c6c307c50c url format tests 2020-03-21 12:08:27 +01:00
antelle b96b477f65 format tests 2020-03-21 11:56:26 +01:00
antelle 4f53e39f8d md-to-html test 2020-03-21 11:45:40 +01:00
antelle 5cac16a632 string format test 2020-03-21 11:37:55 +01:00
antelle a1a02d5098 id generator test 2020-03-21 11:26:49 +01:00
antelle 72c77305e4 password generator tests 2020-03-21 11:23:19 +01:00
antelle d6980ab0b3 up deps 2020-03-20 21:05:39 +01:00
antelle 4ee0a1edaf removed an expensive check from startup 2020-03-20 18:40:43 +01:00
antelle ef7a4ff583 using pkcs11-smartcard-sign 2020-03-19 20:53:30 +01:00
antelle e8979594a1 up deps 2020-03-19 19:56:12 +01:00
antelle 690488abdd rotated the signature key 2020-03-19 19:50:44 +01:00
antelle f7910a1546 Merge pull request #1432 from canthar/maintainer
Fix: MAINTAINER directive in Dockerfile is deprecated
2020-03-19 18:56:30 +01:00
Tomasz Meresiński 42b92ec081 Fix: MAINTAINER directive in Dockerfile is deprecated 2020-03-19 18:34:10 +01:00
antelle b32684ab7b file associations for rpm 2020-03-18 19:52:17 +01:00
antelle eedc4374b9 fix #890: deb will no longer install to /opt 2020-03-17 23:09:46 +01:00
antelle 76304395bd fixed appdata package id 2020-03-17 23:05:04 +01:00
antelle d3dabc35e5 moved appdata package 2020-03-17 23:04:20 +01:00
antelle 039b45e926 renamed appdata package 2020-03-17 23:03:47 +01:00
antelle bf1b162cbc fix #855: appdata file in deb packages 2020-03-17 22:58:08 +01:00
antelle be3c7a8314 fix #784, fix #572, fix #450: more linux releases: AppImage, RPM, Snap 2020-03-17 22:46:21 +01:00
antelle 3bfa95a032 page => tab 2020-03-17 20:17:07 +01:00
antelle 5f1121a241 added a better message for the browser tab 2020-03-17 20:16:44 +01:00
antelle 7ccf38f0df fix #1359: fixed Google Drive login issues in desktop apps 2020-03-17 19:45:38 +01:00
antelle 61d83319d4 KEEWEB_OPEN_DEVTOOLS variable 2020-03-17 07:52:34 +01:00
antelle 1bc8cffbf3 cleaned up code 2020-03-15 18:44:20 +01:00
antelle a7acfb0291 eslint 2020-03-15 18:41:27 +01:00
antelle fb34f8890f #1029: fixed syncing files by timeout when there are no changes 2020-03-15 18:40:37 +01:00
antelle 3d3864d535 #615: translated shortcut modifier keys 2020-03-15 17:34:57 +01:00
antelle 3f9296e38c #411: option to automatically use group icon for new entries 2020-03-15 17:22:25 +01:00
antelle 3a17a370f2 fix #516: scrolling on the open screen on mobile 2020-03-15 17:02:39 +01:00
antelle 42833accc0 #766: setting for no/unlimited history 2020-03-15 15:54:06 +01:00
antelle 85e9a4c4c6 fix #895: generator positioning in list view 2020-03-15 15:19:50 +01:00
antelle 2c0624d5b4 fix #1142: submit button on mobile password input 2020-03-15 13:01:24 +01:00
antelle 347c8fff73 fix #1309: back button in attachment preview 2020-03-15 12:41:02 +01:00
antelle fa17aa4a57 fixed enter keypress in custom field title 2020-03-15 11:51:10 +01:00
antelle 8021c6bb81 fix #1006: password generator patterns 2020-03-15 11:20:01 +01:00
antelle c4be2e5d00 fix #1338: minimized option not working on linux 2020-03-15 10:14:00 +01:00
antelle cbd0c7b228 - fix #1378: screen orientation issues on Android PWA 2020-03-14 21:14:29 +01:00
antelle 0b13c06a09 fix #1293: copying full urls 2020-03-14 21:12:13 +01:00
antelle a5c6180154 fix #1387: fixed drag-drop for otp fields 2020-03-14 21:01:41 +01:00
antelle 19e899ba97 #1393: option to disable saving and exporting (canSaveTo) 2020-03-14 20:51:42 +01:00
antelle 3d9965c4af fix #1391: passwords imported from CSV were not hidden 2020-03-14 20:45:28 +01:00
antelle 98c22a4323 fix #1396: fixed hyperlinks in notes 2020-03-14 20:32:55 +01:00
antelle 649516cf32 removed debug code 2020-03-14 20:30:47 +01:00
antelle 29c0e840d3 up deps 2020-03-14 20:29:55 +01:00
antelle 3a5a7063cd fix #1397: using Segoe UI on Windows 2020-03-14 19:25:00 +01:00
antelle f601dbe313 proper fix #1395 2020-03-14 19:22:48 +01:00
antelle 0640009752 Merge pull request #1427 from harshlele/advanced-search-password
fix #1395 - advanced search will cause a typeerror
2020-03-13 18:05:43 +01:00
Harshal Lele f153d99744 fix #1395 - advanced search will cause a typeerror 2020-03-13 13:37:12 +05:30
antelle 85c07dba9c checking if the directory exists, see #1418 2020-03-09 16:33:28 +01:00
antelle 7ace45929a Merge pull request #1405 from loginov-rocks/patch-2
Make the app installable as PWA
2020-02-10 17:28:46 +01:00
Danila Loginov 212a7a7551 Make the app installable as PWA
In order to be installable as PWA, the app should have at least start_url property in the manifest.

To address https://github.com/keeweb/keeweb/issues/1360
2020-02-06 16:59:42 +03:00
antelle fd9f579802 package-lock.json 2020-01-19 12:28:35 +01:00
antelle ee1b451f59 moved the config a bit later 2020-01-19 12:20:19 +01:00
antelle a2873fd782 Merge pull request #1394 from bradchristensen/bugfix/build-on-windows
Add support for building KeeWeb on Windows
2020-01-19 12:19:29 +01:00
Brad Christensen fc549fe006 Update README to use npm scripts (which use --no-sign by default) 2020-01-19 23:31:32 +13:00
Brad Christensen b931e5d273 Follow the existing convention to use the provided grunt instance 2020-01-19 23:18:50 +13:00
Brad Christensen 25101b5a02 Use Grunt's built-in method of parsing command line args 2020-01-19 23:12:16 +13:00
Brad Christensen 9c32293fa8 Add --no-sign arg to toggle code signing in Grunt 2020-01-19 21:01:59 +13:00
Brad Christensen de6255b388 Fix npm script to run Electron on Windows 2020-01-18 17:21:54 +13:00
Brad Christensen 6566fbe71c Gracefully degrade if code signing config is not available 2020-01-18 17:00:25 +13:00
Brad Christensen 556fc31000 Fix build config to support Windows path separators and newlines 2020-01-18 16:42:36 +13:00
antelle 1072e5778f fix #1385: fixed a file watcher error on network locations 2020-01-05 15:45:06 +01:00
antelle 29bad845b1 Merge pull request #1377 from alex-shpak/cordova
Update cordova launcher, remove unnecessary code.
2019-12-16 22:51:34 +01:00
Alex Shpak a80061d97f Update cordova launcher, remove unnecessary code 2019-12-16 22:37:42 +01:00
antelle bc1d6ce5d8 fixed auto-type text 2019-12-06 18:29:23 +01:00
antelle c6c41d5f2d fixed password generation entropy 2019-11-13 17:00:43 +01:00
antelle 4ded2c1848 simplified generator code a bit 2019-11-13 16:59:22 +01:00
antelle df90fc9c33 Merge branch 'GrantMoyer-develop' into develop 2019-11-13 16:57:37 +01:00
Grant Moyer b1da50133b Remove "binning" from password generation 2019-11-12 20:39:08 -05:00
antelle a65d7208c7 fix #1208: webdav credentials corruption 2019-11-08 19:07:38 +01:00
antelle 36a53cc405 fix #1065: PORTABLE_EXECUTABLE_DIR environment variable 2019-11-06 23:14:20 +01:00
antelle cccb9ac681 fix #1341: auto-lock the app on screen lock on Windows 2019-11-06 23:01:05 +01:00
antelle 0a025d807b Merge branch 'master' into develop
# Conflicts:
#	release-notes.md
2019-11-06 22:59:07 +01:00
antelle 9b07bbd505 Merge branch 'release-1.12' 2019-11-06 19:54:08 +01:00
antelle f224aea444 fixed entry title input size 2019-11-06 19:53:50 +01:00
antelle e21257de0c bump version 2019-11-06 19:48:57 +01:00
antelle ecf2a65e16 fix #1334: saving new files not working 2019-11-06 19:46:17 +01:00
antelle 1f4f3101f2 fix #1335: removed the menubar on Windows and Linux 2019-11-04 21:36:14 +01:00
antelle d66b33fd19 Merge branch 'master' into develop
# Conflicts:
#	release-notes.md
2019-11-03 12:52:37 +01:00
antelle 5d5913233b Merge branch 'release-1.12' 2019-11-03 12:26:29 +01:00
antelle 2b6e8c030d bump version 2019-11-03 12:25:55 +01:00
antelle b1e0056a3a shorter notation 2019-11-03 11:31:46 +01:00
antelle d64eb95388 filtering file info properties 2019-11-03 11:31:08 +01:00
antelle 8794b0d37c fix #1337: displaying groups in trash 2019-11-03 11:24:33 +01:00
antelle beda8972e8 fix #1333: item selection in the auto-type pop-up 2019-11-03 10:04:34 +01:00
antelle c655defe6d fix #1336: saving disabled storage option 2019-11-03 10:00:46 +01:00
antelle 6dc459a64f readme links 2019-11-03 09:51:05 +01:00
antelle 90979be600 Update FUNDING.yml 2019-10-27 22:34:12 +01:00
antelle 6b1361ad9d fix #734: OTP secrets with spaces 2019-10-27 18:59:09 +01:00
antelle bede42388f fixed non-working updater 2019-10-27 16:43:47 +01:00
antelle 604c1bd3d4 Merge branch 'master' into develop
# Conflicts:
#	release-notes.md
2019-10-27 11:05:23 +01:00
antelle 149c565ee6 Merge branch 'release-1.12' 2019-10-27 10:41:42 +01:00
antelle efca3632cc bump version 2019-10-27 10:41:02 +01:00
antelle 60468b4afa fix #1313: disabled code signing for macOS dmg 2019-10-27 10:39:00 +01:00
antelle 50976b2d09 collection tests 2019-10-27 10:35:36 +01:00
antelle 0fce37cc73 fix #1324: duplicated shortcut editor in settings 2019-10-27 09:10:00 +01:00
antelle 12c7313935 fixed electron deprecations 2019-10-26 22:58:48 +02:00
antelle 5d1162bd32 fix #1323: version in the About dialog 2019-10-26 22:56:36 +02:00
antelle 6aa3a71761 Merge branch 'release-1.12' into develop 2019-10-26 21:53:22 +02:00
antelle 3e1f1e557e Merge branch 'develop' 2019-10-26 21:09:08 +02:00
antelle 0a993fb151 languages 2019-10-26 21:08:26 +02:00
antelle e4da7ee601 bump version 2019-10-26 21:05:47 +02:00
antelle d6ef6ecdd8 fix #197: mobile actions panel 2019-10-26 20:50:52 +02:00
antelle e1f242d973 fixed adding new entries on mobile 2019-10-26 19:53:20 +02:00
antelle 1f0503907e up 2019-10-26 19:45:53 +02:00
antelle a9da298dd7 fixed generator on mobile 2019-10-26 19:19:06 +02:00
antelle d3dc13d58a removed hook-rcedit 2019-10-26 14:45:59 +02:00
antelle c7eb8caf8b fix #1319: removed a storage request for invalid passwords 2019-10-26 14:43:34 +02:00
antelle 2ca5f93e8b case 2019-10-17 20:49:36 +02:00
antelle b08ff12760 fix #1310: password generator on the start screen 2019-10-17 19:52:34 +02:00
antelle c62193d1fe #1307: option to disable Markdown support 2019-10-17 19:13:11 +02:00
antelle 858a9bf93b fix #1311: better monospace fonts 2019-10-17 18:53:09 +02:00
antelle 7a22746f67 Merge branch 'master' into develop
# Conflicts:
#	release-notes.md
2019-10-16 22:49:45 +02:00
antelle 92215e8817 Merge branch 'release-1.11' 2019-10-16 22:08:23 +02:00
antelle b449def7e6 bump version 2019-10-16 22:07:43 +02:00
antelle b7f020f69c fix #1263: desktop apps crashes when argon2 is used 2019-10-16 22:07:11 +02:00
antelle be79f67510 fix #1305: WebDAV issues 2019-10-15 20:02:44 +02:00
antelle 57af428b9e Merge branch 'master' into develop
# Conflicts:
#	release-notes.md
2019-10-13 23:27:52 +02:00
antelle 2c9c8b9ab4 Merge branch 'release-1.11' 2019-10-13 23:10:24 +02:00
antelle bc4dbc7de2 bump version 2019-10-13 23:10:05 +02:00
antelle ce55ca1e0d release date 2019-10-13 23:09:46 +02:00
antelle 99bcbc288c fix #1290: generator popup positioning in custom themes 2019-10-13 13:16:57 +02:00
antelle 517134c95b fix #1300: selecting auto-type sequence items issues 2019-10-12 18:56:33 +02:00
antelle e866bac25a fix #1300: selecting auto-type sequence items issues 2019-10-12 18:55:11 +02:00
antelle 0f5b03ce64 model tests 2019-10-12 15:33:48 +02:00
antelle 4d1cbe7f62 closing browser in tests 2019-10-12 14:24:51 +02:00
antelle 69c38cbeca running tests during build 2019-10-12 14:23:19 +02:00
antelle 936de04b1e running tests during build 2019-10-12 14:22:39 +02:00
antelle b8f7a89291 tests 2019-10-12 13:24:37 +02:00
antelle 11a3995722 extracted focus manager 2019-10-12 12:26:22 +02:00
antelle eb68da635f removed an old task 2019-10-12 08:56:23 +02:00
antelle eb2de6f3f2 focus managing refactoring 2019-10-12 08:20:44 +02:00
antelle 5b118667ef Merge branch 'master' into develop
# Conflicts:
#	release-notes.md
2019-10-11 23:51:44 +02:00
antelle f346b73baa Merge branch 'master' into release-1.11 2019-10-11 23:51:03 +02:00
antelle 0fabdac9e0 fixing build 2019-10-11 23:20:32 +02:00
antelle 590035cce9 copying mac helpers 2019-10-11 23:06:36 +02:00
antelle f1d5965bb5 bump version 2019-10-11 21:11:35 +02:00
antelle 85027aa504 Merge branch 'release-1.11' 2019-10-11 21:07:12 +02:00
antelle 72b7517623 release date 2019-10-11 20:57:30 +02:00
antelle 29c3e98c05 fixed issues with some theme plugins 2019-10-11 20:56:35 +02:00
antelle fa15c56f1c Merge pull request #1299 from trickert76/make_docker_image_customizable
Make docker image customizable
2019-10-11 20:29:35 +02:00
antelle 3eca440e0c fix #1296: search in auto-type 2019-10-11 20:26:14 +02:00
Thoralf Rickert-Wendt 9679841e22 #1298 wrong path 2019-10-11 17:49:16 +02:00
Thoralf Rickert-Wendt 16612bface #1298 using url conform delimiter 2019-10-11 17:45:54 +02:00
antelle e48f12de4a Merge pull request #1297 from coliff/patch-1
remove duplicate apple-mobile-web-app-capable meta tag
2019-10-11 17:34:15 +02:00
Thoralf Rickert-Wendt 7b4953a049 #1298 add variable to define a custom configuration within docker 2019-10-11 17:33:50 +02:00
Christian Oliff 6010bf0ba9 remove duplicate apple-mobile-web-app-capable meta tag
the meta tag:
` <meta name="apple-mobile-web-app-capable" content="yes" />`
was appearing twice
2019-10-11 18:49:18 +09:00
antelle 320bc0fe06 fix #1292: macOS app notarization 2019-10-10 23:49:51 +02:00
antelle 0411fe4cfe Merge branch 'master' into develop
# Conflicts:
#	release-notes.md
2019-10-09 23:22:04 +02:00
antelle 9513a6eb80 Merge branch 'master' into release-1.11 2019-10-09 23:21:13 +02:00
Antelle dc6afb765a added a hook for rcedit while wine is not working on macOS 2019-10-09 22:54:32 +02:00
Antelle b944e36d5c Merge branch 'release-1.11' 2019-10-08 20:21:18 +02:00
Antelle 458ba2de77 bump version 2019-10-08 20:19:45 +02:00
antelle 77423ad833 fix #1288: issues when opening a file during in auto-type mode 2019-10-08 20:09:06 +02:00
antelle 3c6c929854 fix #1289: crash on Auto sorting mode 2019-10-08 19:41:08 +02:00
antelle 89a4ef2e4d keeweb-tools 2019-10-07 19:32:51 +02:00
antelle 4644dda250 #1273: using a string from locale while creating new files 2019-10-06 18:53:39 +02:00
antelle 8c124f8980 fix #480: option to launch the app minimized 2019-10-06 13:14:12 +02:00
antelle 769cf19d5c fix #862: downloading attachments on mobile 2019-10-06 12:56:44 +02:00
antelle 42f6c51393 fixed shortcut text 2019-10-06 12:39:38 +02:00
antelle 2a47afa672 better texts on the shortcuts page 2019-10-06 12:33:03 +02:00
antelle 5a8927b547 fix #565: global shortcut to open KeeWeb 2019-10-06 12:27:18 +02:00
antelle cc9e369b6f fix #963: keyboard shortcut to copy OTP in background 2019-10-06 08:48:11 +02:00
antelle 63aee0e876 fix #1108: setting for running in an iframe 2019-10-06 08:28:59 +02:00
antelle dcce37d99e fix #1273: untranslated menu items 2019-10-05 08:37:10 +02:00
antelle 39aaac2d1b Merge branch 'master' into develop 2019-10-04 21:30:44 +02:00
antelle f1a632fb52 Merge branch 'master' into release-1.11 2019-10-04 21:29:39 +02:00
antelle 37ad3fbf0b release date 2019-10-04 21:14:49 +02:00
antelle 87cb6f8262 Merge branch 'release-1.11' 2019-10-04 21:13:43 +02:00
antelle 60eee04922 fixed the opencollective image 2019-10-04 21:13:32 +02:00
antelle 3250816523 manifest update 2019-10-04 20:13:36 +02:00
antelle 7e62173f01 bump version 2019-10-04 20:10:13 +02:00
antelle 6c0124fcf2 fix #1285: issues in moving entries across files 2019-10-04 20:09:44 +02:00
antelle a361fdac9e fixed field name 2019-10-04 19:44:31 +02:00
antelle 911772510c disabled spellcheck on the search input 2019-10-04 19:26:37 +02:00
antelle d2777ba42d fixed advanced entry search 2019-10-03 19:09:22 +02:00
antelle a4b9d1e98b fix #1022: fuzzy search 2019-09-30 20:31:12 +02:00
antelle 3b8e6d7585 up handlebars.js 2019-09-30 19:36:16 +02:00
antelle 7e0565df3b Merge branch 'master' into develop 2019-09-30 19:33:21 +02:00
antelle e8e2b49993 Merge branch 'release-1.11' 2019-09-29 23:26:32 +02:00
antelle a72aea3190 bump version 2019-09-29 23:26:07 +02:00
antelle e97572cfab fix #1279: error opening files with saved keyfiles 2019-09-29 23:25:53 +02:00
antelle 3a0ba29e25 Merge branch 'release-1.11' 2019-09-29 15:45:50 +02:00
antelle f699ece732 bump version 2019-09-29 15:45:27 +02:00
antelle 8bfa1fadda fix #1278: entry selection auto-type window issues 2019-09-29 15:43:17 +02:00
antelle 511fccd084 fix #1277: auto-type window matching on Linux 2019-09-29 15:31:02 +02:00
antelle db091b2b39 readme 2019-09-29 14:37:10 +02:00
antelle fd51fdddb3 fixed displaying errors on the plugins page 2019-09-29 12:35:47 +02:00
antelle bece4a44f1 Merge branch 'release-1.11' 2019-09-29 11:57:49 +02:00
antelle be5dcba4c6 fix #1276: release notes 2019-09-29 11:49:23 +02:00
antelle ae975cdc2f fixed GDrive connection issues 2019-09-29 11:32:03 +02:00
antelle 890097885a bump version 2019-09-29 10:38:58 +02:00
antelle 9a8f595514 fix #1275: starting the app after closing on macOS 2019-09-29 10:34:47 +02:00
antelle 113db1c97d Merge branch 'master' into release-1.11 2019-09-29 10:17:03 +02:00
antelle 11f2355099 fixed eventlisteners leak 2019-09-29 10:06:47 +02:00
antelle a275a895cb Merge branch 'release-1.11' 2019-09-29 10:01:20 +02:00
antelle f84a5a2b51 bump version 2019-09-29 10:00:31 +02:00
antelle 3c0444d812 fixed plugin search filtering 2019-09-29 09:58:45 +02:00
antelle 1c744d8d6b fixed Dropbox connection on iOS 13 homescreen 2019-09-29 09:54:52 +02:00
antelle 82cad800c2 eslint 2019-09-28 23:42:21 +02:00
antelle b6be4375bd fix #1271: loading custom plugins from config 2019-09-28 23:40:17 +02:00
antelle b635281428 Merge branch 'master' into release-1.11 2019-09-28 22:59:18 +02:00
antelle 326b9658fd fix #1271: loading custom plugins from config 2019-09-28 22:47:00 +02:00
antelle d0cc9b54f4 Merge branch 'release-1.11' 2019-09-28 22:32:09 +02:00
antelle 92dec8a7aa bump version 2019-09-28 22:30:42 +02:00
antelle 3e987cc2dc fix #1270: password change control focus 2019-09-28 22:30:21 +02:00
antelle 20843dd1fb Merge branch 'release-1.11' into develop 2019-09-28 20:56:19 +02:00
antelle 29f014abc3 fixed desktop build 2019-09-28 20:27:39 +02:00
antelle 49b5b3d41e fixed desktop apps startup 2019-09-28 20:03:03 +02:00
antelle efb0c39d33 up 2019-09-28 19:36:57 +02:00
antelle 10460f270d Merge branch 'develop' 2019-09-28 19:34:08 +02:00
antelle 0eafc4ac88 bump version 2019-09-28 19:33:27 +02:00
antelle bfc6d4b3c0 field options fix 2019-09-28 19:30:13 +02:00
antelle 9626eb904e fixed trash 2019-09-28 19:26:09 +02:00
antelle c9f62c3f3a fix otp 2019-09-28 19:22:44 +02:00
antelle be52cf86b5 file-changed event 2019-09-28 19:18:24 +02:00
antelle 922c8f2100 languages 2019-09-28 15:50:43 +02:00
antelle 7dbac45670 fixed comments in output 2019-09-28 15:49:04 +02:00
antelle 0dd4fa666a moved a lib 2019-09-28 15:44:46 +02:00
antelle 94aa1665ab release notes 2019-09-28 15:24:26 +02:00
antelle 009d854622 appmodel for keewebhttp 2019-09-28 15:20:29 +02:00
antelle 886d452996 prettier 2019-09-28 14:55:36 +02:00
antelle 0afed3f9aa comment 2019-09-28 14:52:54 +02:00
antelle e42b28ae9e fixed settings shortcuts editor 2019-09-28 14:49:49 +02:00
antelle 0672180233 fixed prop deletion 2019-09-28 14:45:47 +02:00
antelle 0cd401c45d fix #1252: public key rotation 2019-09-28 14:40:46 +02:00
antelle 2913a0421d using one key for everything 2019-09-28 14:17:55 +02:00
antelle 42134b4888 fix a color flash on start 2019-09-28 13:43:30 +02:00
antelle 8b2df9e1c8 about 2019-09-28 13:37:52 +02:00
antelle adb1fd421a fixed details on mobile 2019-09-28 13:31:52 +02:00
antelle f1173c496a plugins for Edge 2019-09-28 13:20:51 +02:00
antelle 59aebd3666 fixed copypaste 2019-09-28 12:25:07 +02:00
antelle 85b89a2d80 fixed layout issues on the import screen 2019-09-28 10:18:00 +02:00
antelle 17dedb6b8e obfuscating displayed password values 2019-09-27 07:37:26 +02:00
antelle 8fb8a9d096 #1125: field actions: copy, reveal, auto-type 2019-09-26 23:43:07 +02:00
antelle 26d0cbf2b2 group selector in csv import 2019-09-26 07:19:20 +02:00
antelle bcee01cdd1 CSV import. fix #498, fix #453 2019-09-25 23:24:38 +02:00
antelle 8060ba6453 fixed the beta build 2019-09-25 22:51:15 +02:00
antelle 62f723ff6f fix #564: Steam OTP support 2019-09-25 22:48:32 +02:00
antelle 86b5113c46 fixed method case 2019-09-25 22:47:44 +02:00
antelle e9fbd49864 Merge branch 'monroe-dylan-m-develop' into develop 2019-09-25 22:46:03 +02:00
Dylan Monroe 9c765ced45 De-linted 2019-09-25 16:25:52 -04:00
Dylan Monroe 4405fdb5fe Fixed typo 2019-09-25 16:04:25 -04:00
Dylan Monroe 645d904954 Removed duplicate assignment 2019-09-25 15:54:39 -04:00
Dylan Monroe b8be888f05 Added Steam TOTP output format 2019-09-25 15:54:10 -04:00
antelle 6aca16c336 prettified service worker 2019-09-23 20:36:54 +02:00
antelle a01d85411c fix #156: using ServiceWorker instead of AppCache 2019-09-23 20:32:56 +02:00
antelle b280c6f723 fixed authHeight property name 2019-09-22 22:30:03 +02:00
antelle f74e2bcc7f symbol name 2019-09-22 22:24:45 +02:00
antelle ae2d54f454 fixed a memory leak 2019-09-22 22:24:19 +02:00
antelle 63be5932be isequal fix 2019-09-22 22:14:45 +02:00
antelle 1565c26823 simple CSV parser 2019-09-22 18:57:18 +02:00
antelle ae72b55a2e fix #336: moving entries across files 2019-09-22 09:56:48 +02:00
antelle b83e2519ac fixed menu resize 2019-09-21 07:41:33 +02:00
antelle 22f5e61978 events in electron 2019-09-21 07:39:03 +02:00
antelle 966097e1ff up 2019-09-20 23:39:12 +02:00
antelle 0c2de37cf8 autoprefixer 2019-09-20 23:37:17 +02:00
antelle 328bdd68e2 bugfixes 2019-09-20 23:25:43 +02:00
antelle a10ee6c9f2 fix 2019-09-20 23:12:02 +02:00
antelle 383847d3aa woff2 2019-09-20 23:03:25 +02:00
antelle 2b8dca7748 added some ids 2019-09-20 22:57:36 +02:00
antelle 9a19339ec5 bugfixes 2019-09-20 22:26:32 +02:00
antelle 2f07c87801 better way of rendering collections 2019-09-20 22:20:53 +02:00
antelle c14567311b fixed file list 2019-09-20 22:18:23 +02:00
antelle bc8aad5062 fix #1256: error during updating the app 2019-09-20 20:35:05 +02:00
antelle a1a649cd9f electron events 2019-09-20 20:31:19 +02:00
antelle ba0586d407 bugfixes 2019-09-20 06:30:04 +02:00
antelle c2212ac4ad Merge branch 'master' into develop
# Conflicts:
#	package.json
#	release-notes.md
2019-09-20 06:01:44 +02:00
antelle 4548829595 release date 2019-09-20 05:58:20 +02:00
antelle 07177222a0 fixed argon2 2019-09-20 05:43:22 +02:00
antelle 723c39de85 up packages 2019-09-19 23:16:18 +02:00
antelle a20dab859f Merge branch 'release-1.10' 2019-09-19 23:06:41 +02:00
antelle acf3bc945c bump version 2019-09-19 23:06:10 +02:00
antelle 379ea9c208 languages 2019-09-19 23:05:44 +02:00
antelle 74f282a69d updated argon2 2019-09-19 23:04:18 +02:00
antelle ef7ae9ada9 Revert "fix #1154: relative Destination header in WebDAV MOVE"
This reverts commit cbbf5f83

fix #1259
2019-09-19 23:01:51 +02:00
antelle 64bf07c71e collection toJSON 2019-09-19 22:07:14 +02:00
antelle 8e30d99e94 at 2019-09-19 18:28:55 +02:00
antelle 0367966ae6 bugfixes 2019-09-19 17:42:53 +02:00
antelle 4d7cef70d2 menu models 2019-09-18 23:37:57 +02:00
antelle 2f93e53716 storage 2019-09-18 21:26:43 +02:00
antelle ebfdff90c7 plugins 2019-09-18 21:15:48 +02:00
antelle 3a5d6bc2ca button padding 2019-09-18 20:43:01 +02:00
antelle 15518a4ce0 removed underscore, added lodash 2019-09-18 20:42:17 +02:00
antelle c41bd1a4ef terser 2019-09-18 19:59:39 +02:00
antelle 9b1335720b less underscore 2019-09-18 07:12:06 +02:00
antelle 731994c9fe less underscore 2019-09-18 07:08:23 +02:00
antelle 3341f3e7f6 less underscore 2019-09-17 23:48:31 +02:00
antelle 08d7261488 less underscore 2019-09-17 23:44:17 +02:00
antelle 89ccb99395 less underscore 2019-09-17 22:17:40 +02:00
antelle 94660d9e71 updater model 2019-09-17 21:56:58 +02:00
antelle 8f4932610c runtime-data model 2019-09-17 21:50:46 +02:00
antelle b405ca970c file model 2019-09-17 21:39:06 +02:00
antelle 05b12c2d59 attachment model 2019-09-17 20:08:58 +02:00
antelle 268dfee75d app model 2019-09-17 19:58:39 +02:00
antelle 9c3c9d28fa app setting model 2019-09-17 19:50:42 +02:00
antelle 00291da933 models and collections 2019-09-17 19:01:24 +02:00
antelle 87eb0468a6 events 2019-09-17 19:01:12 +02:00
antelle f2fe249560 fix 2019-09-16 23:36:22 +02:00
antelle 42e70c1d05 key handler 2019-09-16 23:32:05 +02:00
antelle 19fa54f9d0 otp qr reader 2019-09-16 23:27:31 +02:00
antelle ec6a6e08ff fix 2019-09-16 23:19:54 +02:00
antelle 39e683baf0 cleanup 2019-09-16 23:10:22 +02:00
antelle 2fcc6f2ea3 events 2019-09-16 22:57:56 +02:00
antelle 7f30350873 readme 2019-09-16 22:03:03 +02:00
antelle 9859e921d2 exports 2019-09-16 22:01:59 +02:00
antelle 0dea89c0de event listeners 2019-09-16 21:49:21 +02:00
antelle 1aa29237e2 Merge branch 'views' into develop 2019-09-16 21:08:20 +02:00
antelle 727887fb79 bugfixes 2019-09-16 21:07:39 +02:00
antelle 12079f6ac6 bugfixes 2019-09-16 20:54:14 +02:00
antelle f1d9b5c645 moved views 2019-09-16 20:42:33 +02:00
antelle 75b4ed05ab settings views 2019-09-16 20:40:20 +02:00
antelle a2f938b0a0 removed some readme paragraphs 2019-09-16 20:12:18 +02:00
antelle 8869a27ac9 field views 2019-09-16 19:55:06 +02:00
antelle 927278317e fixed list clicks 2019-09-16 19:26:31 +02:00
antelle ccace95a6c details view 2019-09-16 19:24:15 +02:00
antelle 813ed6d541 linter fix 2019-09-16 19:10:14 +02:00
antelle e7d13ff254 details views 2019-09-16 19:09:57 +02:00
antelle b16dd74492 details views 2019-09-16 18:41:06 +02:00
antelle 2bcaa1926a jsconfig for vscode 2019-09-16 18:34:58 +02:00
antelle 1a48270a28 fake config for IDE's 2019-09-16 18:18:51 +02:00
antelle 6606fa8108 fix 2019-09-16 17:58:44 +02:00
antelle 7730486f30 move views 2019-09-16 17:43:57 +02:00
antelle ad0963e412 key change view 2019-09-16 07:13:56 +02:00
antelle 5ae07b721a dropdown view 2019-09-16 07:06:55 +02:00
antelle a695b35eca fix 2019-09-16 06:56:39 +02:00
antelle 2ce1d01535 storage-file-list view 2019-09-15 23:41:00 +02:00
antelle f8f8a7c1d1 open-config view 2019-09-15 23:24:53 +02:00
antelle 6277a48419 modal view 2019-09-15 23:18:09 +02:00
antelle 155eb493bf list-wrap view 2019-09-15 23:08:36 +02:00
antelle de2443eb5a auto-type-select view 2019-09-15 23:02:51 +02:00
antelle c9ac7f2fa3 drag view 2019-09-15 21:22:23 +02:00
antelle 22d1b478f9 auto-type-hint-view 2019-09-15 20:17:08 +02:00
antelle 43b11277ad icon select view 2019-09-15 20:09:28 +02:00
antelle 7589a112d0 view refactoring 2019-09-15 18:33:45 +02:00
antelle 9bbea458c6 imports 2019-09-15 14:16:32 +02:00
antelle 556c5dd56a moved phonetic export 2019-09-15 13:30:38 +02:00
antelle 2688e761ba moved PluginManager 2019-09-15 13:29:20 +02:00
antelle 5a10dc1f2f removed unnecessary exports 2019-09-15 13:27:24 +02:00
antelle 9c1de2aca9 moved storage modules 2019-09-15 13:24:53 +02:00
antelle c83dff46a7 renamed the mixin 2019-09-15 12:41:38 +02:00
antelle 3bae948218 grammar 2019-09-15 12:40:25 +02:00
antelle 6551622e07 fixed an error message 2019-09-15 12:37:11 +02:00
antelle 3319478876 updated browserslist 2019-09-15 12:18:21 +02:00
antelle 58b8ed7940 renamed mixins to view-engine 2019-09-15 12:14:53 +02:00
antelle bc808889a1 removed some view methods 2019-09-15 12:12:00 +02:00
antelle 5cd19cee56 protected-value-ex 2019-09-15 12:09:18 +02:00
antelle f82791096d renamed helpers 2019-09-15 08:51:24 +02:00
antelle 58726de491 path fix 2019-09-15 08:49:41 +02:00
antelle 60dcfbb071 organized files inside comp 2019-09-15 08:47:57 +02:00
antelle 9e7a86a1db organized files inside util 2019-09-15 08:11:11 +02:00
antelle 0028f2293f checking if devtools are supported before adding a shortcut 2019-09-15 07:47:45 +02:00
antelle e7d88cce58 fix #1141: opening file from storage if cache is not available 2019-09-15 07:44:04 +02:00
antelle 73635e2784 fix plugin gallery layout on mobile 2019-09-14 23:35:10 +02:00
antelle 92d4a40228 about 2019-09-14 22:32:35 +02:00
antelle 0b8bc1afb0 fixed a warning in XHR.send 2019-09-14 22:21:21 +02:00
antelle 27d86d8185 webpack fix 2019-09-14 22:14:44 +02:00
antelle dbc73a73e2 fix #713: markdown notes 2019-09-14 22:12:02 +02:00
antelle f7ef9a7b4a wording 2019-09-14 17:09:35 +02:00
antelle b06cb26edc fix #743: copying entry fields to clipboard 2019-09-14 17:06:38 +02:00
antelle 56d84e1d18 fix #348: configurable system-wide shortcuts 2019-09-14 16:36:30 +02:00
antelle 3859beb543 devtools are now opened with alt-cmd-I 2019-09-14 14:07:56 +02:00
antelle 1b2f83ea80 fix #502: increased the default value of encryption rounds 2019-09-14 13:47:47 +02:00
antelle ba122e786c fix #1255: file format version and kdf selection in settings 2019-09-14 09:34:23 +02:00
antelle cdedcd9dac babel preset-env 2019-09-13 23:25:57 +02:00
antelle 2214356d27 es6 2019-09-13 20:34:52 +02:00
antelle 02b7266206 updated windows helper for #554 2019-09-12 23:37:31 +02:00
antelle e0291b2d52 fix #554: checking active window id during auto-type 2019-09-12 22:38:21 +02:00
antelle 068e49c53c checking modal before closing the dropdown 2019-09-12 20:21:49 +02:00
antelle 0fe67c9e4a Revert "fix #1154: relative Destination header in WebDAV MOVE"
This reverts commit cbbf5f83

fix #1259
2019-09-12 20:09:45 +02:00
antelle 79dd95facd fix #1243: auto-type any field 2019-09-12 19:59:35 +02:00
antelle 9e5d6403fa fixed auto-type select view on macos theme 2019-09-12 07:12:52 +02:00
antelle 0a9296c6c4 fix #107: multiline custom fields support 2019-09-11 23:50:18 +02:00
antelle 07df05304e fix multi-line fields display in history 2019-09-11 23:04:28 +02:00
antelle 5d0556debc fix #1226: 7-digit Authy OTP support 2019-09-11 22:41:00 +02:00
antelle 789103a2b8 fix #764: multiple attachments display 2019-09-11 22:25:33 +02:00
antelle f48713409b spacing fix 2019-09-09 22:10:29 +02:00
antelle 8ecae7e745 Merge branch 'master' into develop 2019-09-09 17:30:03 +02:00
antelle 1b64dd6d56 fix build 2019-09-09 17:13:28 +02:00
antelle d4c255e240 Merge branch 'develop' 2019-09-09 17:10:44 +02:00
antelle 09894d1c8f set version 2019-09-09 17:09:42 +02:00
antelle 574fa84f7d fix set-version 2019-09-09 17:08:31 +02:00
antelle 0953a29b4e prettier 2019-09-09 17:07:24 +02:00
antelle e82732c8c0 up languages 2019-09-09 17:06:29 +02:00
antelle e2588e81f8 bump version 2019-09-09 17:03:39 +02:00
antelle c525d1f9e0 padding 2019-09-09 17:01:47 +02:00
antelle b21b9cd24e fix 2019-09-09 16:56:32 +02:00
antelle 31b0097afb fixed links 2019-09-09 16:54:14 +02:00
antelle e6aef150ee fix #1244: deb file permissions issue 2019-09-09 16:24:45 +02:00
antelle aa0d3d329e Merge branch 'master' into develop 2019-09-09 08:34:26 +02:00
antelle a9ae7ad815 removed stale bot config 2019-09-09 08:33:57 +02:00
antelle 65ba766b0f mobile fixes 2019-09-08 21:21:20 +02:00
antelle bd37cb2c26 field order 2019-09-08 20:29:07 +02:00
antelle 5703dceb0c HTML export 2019-09-08 20:28:02 +02:00
antelle 15b170db5d pretty-printing exported XML files 2019-09-08 18:09:13 +02:00
antelle ef71035e0d fixed tip size 2019-09-08 15:29:02 +02:00
antelle 7977bbf6e1 smooth window startup color transition for the dark theme 2019-09-08 15:11:41 +02:00
antelle a7f769d4f6 new screenshot 2019-09-08 15:07:34 +02:00
antelle a634d824d0 fixed calendar styles 2019-09-08 14:59:08 +02:00
antelle 42f0cc307f grammar 2019-09-08 14:39:06 +02:00
antelle 68e5955d09 mac colors 2019-09-08 14:38:26 +02:00
antelle 3df178a026 confirmation for deleting an entry on mobile 2019-09-08 14:20:11 +02:00
antelle ba57bf9503 updated the demo file 2019-09-08 14:14:07 +02:00
antelle c216d785aa displaying websites as HTTPS if no scheme is provided 2019-09-08 14:11:33 +02:00
antelle f4359fef92 fixed field editing issues 2019-09-08 14:10:35 +02:00
antelle 13f90d7a39 up bourbon 2019-09-08 13:43:55 +02:00
antelle 135c4dc60e grammar 2019-09-08 13:13:30 +02:00
antelle a78c63b05b style adjustments 2019-09-08 13:10:01 +02:00
antelle e3081cba17 changed the icon of automatic search 2019-09-08 12:59:45 +02:00
antelle bfbfaf559a fixed the button position 2019-09-08 12:54:29 +02:00
antelle 6e03932e6d show the macOS theme only on Apple devices 2019-09-08 12:53:05 +02:00
antelle c5f2bd4aa3 fix generator 2019-09-08 11:50:26 +02:00
antelle ba56444a6e fixed paddings 2019-09-08 11:46:03 +02:00
antelle 56fbc14893 picker 2019-09-08 11:32:31 +02:00
antelle 7f20e6cc46 mobile fix 2019-09-08 11:05:38 +02:00
antelle 6dba3f9bf7 macos dark theme 2019-09-08 10:54:18 +02:00
antelle 47b2c32031 bg 2019-09-08 09:56:41 +02:00
antelle 7a3281bd23 up argon2-browser 2019-09-08 09:55:46 +02:00
antelle 55f4ff8f73 eslint 2019-09-08 09:39:30 +02:00
antelle c5d8732031 up deps 2019-09-08 09:38:31 +02:00
antelle 2181c9aa91 dropped support for browsers without css variables 2019-09-08 09:31:25 +02:00
antelle 82f841fdf9 macOS dark theme 2019-09-08 09:12:15 +02:00
antelle bebb9a88eb fixed field editing styles 2019-09-08 08:25:15 +02:00
antelle 8df70602c0 Merge branch 'master' into develop 2019-09-07 21:16:57 +02:00
antelle ef39b5c79c donation link changed 2019-09-07 21:15:20 +02:00
antelle a77dd32d20 donation link 2019-09-07 21:06:33 +02:00
antelle c4dc65761c Merge branch 'open-collective' 2019-09-07 20:55:06 +02:00
antelle bc6d3fba55 removed paypal 2019-09-07 20:34:25 +02:00
antelle 1cf5171526 removed paypal 2019-09-07 20:33:46 +02:00
antelle db850ece85 wording 2019-09-07 20:29:49 +02:00
antelle be3acbe13a funding 2019-09-07 20:23:50 +02:00
antelle 670fc425ac link 2019-09-07 20:23:04 +02:00
antelle 83bd89fe50 opencollective button 2019-09-07 20:21:32 +02:00
antelle c4489d1ea0 npm audit fix 2019-09-07 19:31:25 +02:00
antelle 82a11aaf4f Merge branch 'release-1.9' 2019-09-07 19:29:41 +02:00
antelle 04a513556b bump version 2019-09-07 19:28:59 +02:00
antelle d670deb0cb Merge branch 'master' into release-1.9 2019-09-07 19:24:48 +02:00
antelle cc089b2bd1 release notes 2019-09-07 19:23:14 +02:00
antelle e812218919 fix titlebar color on macOS dark theme 2019-09-07 19:22:45 +02:00
antelle 35b531dad0 release notes 2019-09-07 19:21:48 +02:00
antelle 6715c614ac fix titlebar color on macOS dark theme 2019-09-07 19:16:09 +02:00
antelle 1a7975072f Merge branch 'master' into develop 2019-09-05 22:34:56 +02:00
antelle 2dc9959ca4 fixed menu padding issues in some browsers 2019-09-05 22:30:04 +02:00
antelle a69a5a5472 Stale bot config 2019-09-02 07:34:31 +02:00
antelle b689c96870 xml files can be now opened as regular files 2019-08-25 12:46:53 +02:00
antelle ea00818573 fix #1129: webdav storage error on Unicode filenames 2019-08-24 07:47:13 +02:00
antelle cbbf5f833a fix #1154: relative Destination header in WebDAV MOVE 2019-08-24 07:37:08 +02:00
antelle 8a258998dd fixed group settings not being displayed 2019-08-24 07:14:29 +02:00
antelle 80c44c4c03 fixed group settings not being displayed 2019-08-24 07:09:53 +02:00
antelle ba122bd9d0 fix #1241: config option to disable xml export (canExportXml) 2019-08-24 06:56:25 +02:00
antelle 58709c33a0 added a forgotten comma 2019-08-22 22:49:55 +02:00
antelle 087b1937de Merge branch 'master' into release-1.9 2019-08-22 22:42:02 +02:00
antelle 54430cd83d Merge branch 'develop' 2019-08-22 22:26:25 +02:00
antelle a35817c379 up languages 2019-08-22 22:25:59 +02:00
antelle 9375f5c281 bump version 2019-08-22 22:23:38 +02:00
antelle ba29687865 fix #1234 auto-type issues in xubuntu/xfce 2019-08-22 22:15:04 +02:00
antelle c5c64bee20 fix #1235: custom themes loading 2019-08-20 20:18:16 +02:00
antelle 74e9bb5fc7 Merge branch 'master' into develop 2019-08-19 23:34:39 +02:00
antelle e6556ca92d 2019 2019-08-19 23:33:52 +02:00
antelle 9737272e19 Create FUNDING.yml 2019-08-19 23:17:05 +02:00
antelle f5b4a2a887 Merge branch 'master' into release-1.9 2019-08-19 21:04:10 +02:00
antelle d16f335627 up de 2019-08-19 21:03:33 +02:00
antelle 46adf5dcc1 version 2019-08-19 20:59:54 +02:00
antelle 2c38f3c8f2 fix #1234: auto-type not working on linux 2019-08-19 20:55:25 +02:00
antelle 105205661f fix #1232: removed an unwanted menubar on windows and linux 2019-08-19 20:10:58 +02:00
antelle a69cf5cd85 improved ranking search 2019-08-18 16:14:47 +02:00
antelle 7c5b76fda3 fix #1231: tooltip arrow positioning 2019-08-18 14:44:51 +02:00
antelle 7e2d531533 Merge branch 'release-1.9' into develop 2019-08-18 11:39:12 +02:00
antelle 64c41785f6 removed linux-ia32 2019-08-18 11:24:25 +02:00
antelle 69a3dd14ba removed old lib 2019-08-18 11:21:24 +02:00
antelle 2a4ed6f264 removed support for linux/ia32
See more details here: https://electronjs.org/blog/linux-32bit-support
2019-08-18 11:17:00 +02:00
antelle ba2d9415be version 2019-08-18 11:10:27 +02:00
antelle 60dfb3c21f Merge branch 'develop' 2019-08-18 11:08:42 +02:00
antelle 9816ab5c80 eslintrc 2019-08-18 10:18:18 +02:00
antelle 904a1e12d2 release notes 2019-08-18 10:17:54 +02:00
antelle f8395f7f38 better eslint 2019-08-18 10:17:09 +02:00
antelle 0df1ba97d5 min electron version 2019-08-18 08:19:39 +02:00
antelle d581cb13af release notes 2019-08-18 08:18:36 +02:00
antelle ede597d67e comma 2019-08-18 08:17:32 +02:00
antelle fe7078aebf version 2019-08-18 08:16:10 +02:00
antelle 2f855d5c8a deleted old file 2019-08-18 08:15:46 +02:00
antelle 6788b77f32 year 2019-08-18 08:12:11 +02:00
antelle 2bb4584235 prettier path 2019-08-18 08:10:45 +02:00
antelle 3e3d3571be eslint 2019-08-18 08:09:42 +02:00
antelle fa4ff0b0c3 prettier 2019-08-18 08:05:38 +02:00
antelle 176c2a6edd moved the loader 2019-08-18 07:58:23 +02:00
antelle 74a005d0e3 removed an unused field 2019-08-17 20:09:24 +02:00
antelle 02bb56357f better error description 2019-08-17 19:30:42 +02:00
antelle d9ad69b085 readme 2019-08-17 17:59:24 +02:00
antelle 824b0d3e3c readme 2019-08-17 17:58:00 +02:00
antelle 8ab1ec615f bugfixes for new Electron and webpack 2019-08-17 15:20:00 +02:00
antelle 5fb3228841 release notes 2019-08-17 13:36:30 +02:00
antelle 0e4538650d fix #1171: enabled updater on Linux 2019-08-17 13:36:03 +02:00
antelle 012bc61f4a fixed electron script 2019-08-17 13:17:54 +02:00
antelle 0d126ae0d8 fix #1166: prevent webdav password logging 2019-08-17 11:39:22 +02:00
antelle 2c064989c1 fix #1215: url matching when there's no website field 2019-08-17 11:28:45 +02:00
antelle 51cc550502 fix #1209: copying app information to clipboard 2019-08-17 11:15:23 +02:00
antelle e2e7176b51 readme 2019-08-17 10:51:46 +02:00
antelle de784bd95c readme 2019-08-17 10:48:16 +02:00
antelle 854e627065 fixed editorconfig 2019-08-16 23:09:14 +02:00
antelle 84a23e4aea prettier 2019-08-16 23:05:39 +02:00
antelle 68245629e4 fixed argon2 2019-08-16 22:30:03 +02:00
antelle fd0a8287dc fix fonts 2019-08-16 22:04:29 +02:00
antelle ebd0578ea2 up deps 2019-08-16 21:51:50 +02:00
antelle e1b0409648 up deps 2019-08-16 21:50:23 +02:00
antelle 17a777b7e6 readme 2019-08-16 21:36:30 +02:00
antelle 336c80e296 up eslint 2019-08-16 21:36:22 +02:00
antelle fcd8a99924 ignored .iml 2019-08-16 20:03:58 +02:00
antelle a7096b5cdf building css with webpack 2019-08-16 18:45:11 +02:00
antelle 32b4e99c12 merge GrantMoyer-develop: option to hide password in the generator 2019-08-15 22:08:26 +02:00
antelle c2658395c0 fixed generator style issues in Firefox, see #1222 2019-08-15 21:25:02 +02:00
antelle d3935a49de up node-sass 2019-08-15 21:25:02 +02:00
Grant Moyer 4892e7aa2b Only create a hidden input if not simpleCopy 2019-08-14 23:20:03 -04:00
Grant Moyer d96f458a1b Easy requested changes 2019-08-14 22:59:53 -04:00
Grant Moyer 93b05e448e Remove hide button from copy mode of password generator
Also fix a regression I had introduced
2019-08-07 19:49:27 -04:00
antelle 63f68dff04 fixed generator style issues in Firefox, see #1222 2019-08-07 20:32:38 +02:00
antelle 7d0760469a up node-sass 2019-08-07 20:30:00 +02:00
Grant Moyer 065ca2dad4 Remove extraneous change and fix indentation 2019-08-06 22:25:57 -04:00
Grant Moyer 03f566e7cd Fix copying hidden password 2019-08-06 20:07:55 -04:00
Grant Moyer 9c8ebde19d Move hide button to top of dialog 2019-08-06 18:48:21 -04:00
Grant Moyer ebcbe6496a Add tooltip to password hiding button 2019-08-05 22:24:26 -04:00
Grant Moyer a2a5d6d10a Remove existing tooltip when creating a new one 2019-08-05 22:23:54 -04:00
Grant Moyer 276afa42da Add option to hide generated password 2019-08-05 19:22:29 -04:00
antelle 2437ae575c fix #1221: added '30 min' lock option 2019-08-05 18:47:01 +02:00
antelle ce5b0cb303 copy the cookies file if it's not possible to move it 2019-04-25 18:17:37 +02:00
antelle 1357c7cb1c fixed a phrase 2019-04-23 19:06:05 +02:00
antelle 2c334f4346 fixed a phrase 2019-04-23 19:05:41 +02:00
antelle 0a7c0f64d2 Merge branch 'master' into develop 2019-04-22 11:47:41 +02:00
emyarod 9427d2191a bump kdbxweb version 2019-04-22 11:43:29 +02:00
antelle 8096353e6e bump version 2019-04-22 11:43:29 +02:00
antelle 3f400a8b2a fix #1163: fixed libgconf-2-4 dependency 2019-04-22 11:43:29 +02:00
antelle 3ddefff1df merge emyarod/1161-bump-kdbxweb-version develop 2019-04-20 09:30:30 +02:00
emyarod ddd5370f69 bump kdbxweb version 2019-04-15 13:17:05 -07:00
antelle 6f203f0a3e removed obsolete code 2019-04-13 11:04:31 +02:00
antelle c795784417 Merge branch 'master' into develop 2019-04-05 20:49:31 +02:00
antelle 47eb538444 Merge pull request #1153 from dploeger/fix-1152
Fixed missing preparation for filter on autotype
2019-04-04 19:16:25 +02:00
Dennis Ploeger fa136af90a bug: Fixed missing preparation for filter on autotype 2019-04-02 14:09:12 +02:00
Dennis Ploeger 1ab397be0a bug: Fixed missing preparation for filter on autotype 2019-04-02 14:08:56 +02:00
622 changed files with 46107 additions and 29808 deletions
+14
View File
@@ -0,0 +1,14 @@
{
"presets": [],
"plugins": [
["@babel/plugin-proposal-class-properties", { "loose": true }],
["@babel/plugin-proposal-object-rest-spread", { "loose": true,
"useBuiltIns": true
}],
"@babel/plugin-proposal-optional-catch-binding",
"@babel/plugin-proposal-optional-chaining",
"@babel/plugin-proposal-nullish-coalescing-operator",
"@babel/plugin-proposal-logical-assignment-operators",
"@babel/plugin-external-helpers"
]
}
+1 -13
View File
@@ -15,17 +15,5 @@ trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false
[*.json]
indent_size = 2
[.eslintrc]
indent_size = 4
[*.scss]
indent_size = 2
[*.css]
indent_size = 2
[*.nsh]
[{*.nsh,*.yml,*.yaml,*.json}]
indent_size = 2
+34 -4
View File
@@ -1,7 +1,7 @@
{
"extends": "standard",
"plugins": ["prettier", "import", "babel"],
"extends": ["standard", "eslint:recommended", "plugin:prettier/recommended"],
"rules": {
"indent": ["error", 4, { "SwitchCase": 1 }],
"semi": ["error", "always"],
"one-var": "off",
"space-before-function-paren": "off",
@@ -15,13 +15,42 @@
"no-useless-escape": "off",
"no-var": "error",
"prefer-const": "error",
"no-unused-expressions": "error",
"no-unused-expressions": "off",
"strict": ["error", "never"],
"no-mixed-operators": "off",
"prefer-promise-reject-errors": "off",
"standard/no-callback-literal": "off",
"object-curly-spacing": "off",
"quote-props": "off",
"no-new-object": "error",
"object-shorthand": "error",
"no-array-constructor": "error",
"array-callback-return": "error",
"no-eval": "error",
"no-new-func": "error",
"prefer-rest-params": "error",
"prefer-spread": "error",
"no-useless-constructor": "error",
"no-dupe-class-members": "error",
"no-duplicate-imports": "error",
"eqeqeq": "error",
"no-unneeded-ternary": "error",
"curly": "error",
"prettier/prettier": "error",
"no-empty": "off",
"no-restricted-syntax": [
"error",
{
"selector": "ExportDefaultDeclaration",
"message": "Prefer named exports"
}
],
"import/no-webpack-loader-syntax": "off",
"object-curly-spacing": "off"
"import/no-relative-parent-imports": "error",
"import/first": "error",
"import/no-default-export": "error",
"babel/no-unused-expressions": "error",
"node/no-callback-literal": "off"
},
"parserOptions": {
"sourceType": "module",
@@ -29,6 +58,7 @@
"impliedStrict": true
}
},
"parser": "babel-eslint",
"globals": {
"_": true,
"$": true
+12
View File
@@ -0,0 +1,12 @@
# These are supported funding model platforms
github: [keeweb, antelle]
patreon: # Replace with a single Patreon username
open_collective: keeweb
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # for example PayPal links
+2 -2
View File
@@ -2,7 +2,7 @@
name: Bug report
about: Create a report to help us improve KeeWeb
title: ''
labels: ''
labels: 'bug'
assignees: ''
---
@@ -24,7 +24,7 @@ A clear and concise description of what you expected to happen.
If applicable, add screenshots to help explain your problem.
**Environment**
Your user-agent (from Settings/Help section)
Please copy all version information from Settings/Help
**Kdbx File**
Does it happen on Demo or New database?
+1
View File
@@ -0,0 +1 @@
blank_issues_enabled: true
+1 -1
View File
@@ -2,7 +2,7 @@
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
labels: 'enhancement'
assignees: ''
---
+11
View File
@@ -0,0 +1,11 @@
FROM snapcore/snapcraft:stable
COPY entrypoint.sh /entrypoint.sh
RUN apt-get update
RUN apt-get install -y build-essential git-core unzip curl pkg-config rpm
RUN curl -sL https://deb.nodesource.com/setup_15.x | sudo -E bash -
RUN apt-get install -y nodejs
RUN npm i -g grunt-cli
ENTRYPOINT ["/entrypoint.sh"]
+5
View File
@@ -0,0 +1,5 @@
name: 'Linux Build'
description: 'Build KeeWeb on Linux in Docker'
runs:
using: 'docker'
image: 'Dockerfile'
+5
View File
@@ -0,0 +1,5 @@
#!/bin/bash -e
cd /github/workspace
npm ci
grunt desktop-linux
+404
View File
@@ -0,0 +1,404 @@
#!/usr/bin/env python3
#
# git-restore-mtime - Change mtime of files based on commit date of last change
#
# Copyright (C) 2012 Rodrigo Silva (MestreLion) <linux@rodrigosilva.com>
#
# 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. See <http://www.gnu.org/licenses/gpl.html>
#
"""
Change the modification time (mtime) of all files in work tree, based on the
date of the most recent commit that modified the file.
Useful prior to generating release tarballs, so each file is archived with a
date that is similar to the date when the file was actually last modified,
assuming the actual modification date and its commit date are close.
By default ignores all ignored and untracked files, and also refuses to work
on trees with uncommitted changes.
"""
# TODO:
# - Add -z on git whatchanged/ls-files so we don't deal with filename decode/OS normalization
# - When Python is bumped to 3.7, use text instead of universal_newlines on subprocess
# - Update "Statistics for some large projects" with modern hardware and repositories.
# - Create a README.md for git-restore-mtime alone. It deserves extensive documentation
# - Move Statistics there
# FIXME:
# - When current dir is outside the worktree, e.g. using --work-tree, `git ls-files`
# assume any relative pathspecs are to worktree root, not the current dir. As such,
# relative pathspecs may not work.
# - Renames and mode changes should not change file mtime:
# - Must check on status 'R100' and mode changes with same blobs
# - Should require status to be (A, C, M, R<100, T). D will never be processed as
# filelist is a subset of lsfileslist.
# - Check file (A, D) for directory mtime is not sufficient:
# - Renames also change dir mtime, unless rename was on a parent dir
# - If most recent change of all files in a dir was a [M]odification,
# dir might not be touched at all.
# - Dirs containing only subdirectories but no direct files will also
# not be touched. They're files' [grand]parent dir, but never their dirname().
# - Some solutions:
# - After files done, perform some dir processing for missing dirs, finding latest
# file (A, D, R)
# - Simple approach: dir mtime is most recent child (dir or file) mtime
# - Use a virtual concept of "created at most at" to fill missing info, bubble up
# to parents and grandparents
# - When handling [grand]parent dirs, stay inside <pathspec>
# - Better handling of merge commits. `-m` is plain *wrong*. `-c/--cc` is perfect, but
# painfully slow. First pass without merge commits is not accurate. Maybe add a new
# `--accurate` mode for `--cc`?
if __name__ != "__main__":
raise ImportError("{} should not be used as a module.".format(__name__))
import subprocess, shlex
import sys, os.path
import logging
import argparse
import time
# Update symlinks only if the OS supports not following them
UPDATE_SYMLINKS = bool(os.utime in getattr(os, 'supports_follow_symlinks', []))
STEPMISSING = 100
# Command-line interface ######################################################
def parse_args():
parser = argparse.ArgumentParser(
description="""Restore original modification time of files based on the date of the
most recent commit that modified them. Useful when generating release tarballs.""")
group = parser.add_mutually_exclusive_group()
group.add_argument('--quiet', '-q', dest='loglevel',
action="store_const", const=logging.WARNING, default=logging.INFO,
help="Suppress informative messages and summary statistics.")
group.add_argument('--verbose', '-v', action="count",
help="Print additional information for each processed file.")
parser.add_argument('--force', '-f', action="store_true",
help="Force execution on trees with uncommitted changes.")
parser.add_argument('--merge', '-m', action="store_true",
help="""Include merge commits. Leads to more recent mtimes and more files per
commit, thus with the same mtime (which may or may not be what you want). Including
merge commits may lead to less commits being evaluated (all files are found sooner),
which improves performance, sometimes substantially. But since merge commits are
usually huge, processing them may also take longer, sometimes substantially.
By default merge logs are only used for files missing from regular commit logs.""")
parser.add_argument('--first-parent', action="store_true",
help="""Consider only the first parent, the "main branch", when parsing merge
commit logs. Only effective when merge commits are included in the log, either
by --merge or to find missing files after first log parse. See --skip-missing.""")
parser.add_argument('--skip-missing', '-s',
action="store_false", default=True, dest="missing",
help="""Do not try to find missing files. If some files were not found in regular
commit logs, by default it re-tries using merge commit logs for these files (if
--merge was not already used). This option disables this behavior, which may slightly
improve performance, but files found only in merge commits will not be updated.""")
parser.add_argument('--no-directories', '-D',
action="store_false", default=True, dest='dirs',
help="""Do not update directory mtime for files created, renamed or deleted in it.
Note: just modifying a file will not update its directory mtime.""")
parser.add_argument('--test', '-t', action="store_true", default=False,
help="Test run: do not actually update any file")
parser.add_argument('--commit-time', '-c',
action='store_true', default=False, dest='commit_time',
help="Use commit time instead of author time")
parser.add_argument('pathspec', nargs='*', metavar='PATH',
help="""Only modify paths matching PATH, directories or files, relative to current
directory. Default is to modify all files handled by git, ignoring untracked files
and submodules.""")
parser.add_argument('--work-tree', dest='workdir',
help="Path to the work tree, if not current directory or one of its parents.")
parser.add_argument('--git-dir', dest='gitdir',
help="Path to the git repository, if not the default <work-tree-root>/.git")
parser.add_argument('--skip-older-than', metavar='SECONDS', type=int,
help="""Do not modify files that are older than %(metavar)s.
It can significantly improve performance if fewer files are processed.
Useful on CI builds, which can eventually switch workspace to different branch,
but mostly performs builds on the same one (e.g. master).
""")
return parser.parse_args()
# Helper functions ############################################################
def setup_logging(args):
TRACE = logging.DEBUG // 2
logging.Logger.trace = lambda _, m, *a, **k: _.log(TRACE, m, *a, **k)
level = (args.verbose and max(TRACE, logging.DEBUG // args.verbose)) or args.loglevel
logging.basicConfig(level=level, format='%(message)s')
return logging.getLogger()
def normalize(path):
"""Normalize paths from git, handling non-ASCII characters.
Git for Windows, as of v1.7.10, stores paths as UTF-8 normalization form C. If path
contains non-ASCII or non-printable chars it outputs the UTF-8 in octal-escaped
notation, double-quoting the whole path. Double-quotes and backslashes are also escaped.
https://git-scm.com/docs/git-config#Documentation/git-config.txt-corequotePath
https://github.com/msysgit/msysgit/wiki/Git-for-Windows-Unicode-Support
https://github.com/git/git/blob/master/Documentation/i18n.txt
Example on git output, this function reverts this:
r'back\slash_double"quote_açaí' -> r'"back\\slash_double\"quote_a\303\247a\303\255"'
"""
if path and path[0] == '"':
# Python 2: path = path[1:-1].decode("string-escape")
# Python 3: https://stackoverflow.com/a/46650050/624066
path = (path[1:-1] # Remove enclosing double quotes
.encode('latin1') # Convert to bytes, required 'unicode-escape'
.decode('unicode-escape') # Perform the actual octal-escaping decode
.encode('latin1') # 1:1 mapping to bytes, forming UTF-8 encoding
.decode('utf8')) # Decode from UTF-8
# Make sure the slash matches the OS; for Windows we need a backslash
return os.path.normpath(path)
if UPDATE_SYMLINKS:
def touch(path, mtime, test=False):
"""The actual mtime update"""
if test: return
os.utime(path, (mtime, mtime), follow_symlinks=False)
else:
def touch(path, mtime, test=False):
"""The actual mtime update"""
if test: return
os.utime(path, (mtime, mtime))
def isodate(secs):
return time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(secs))
# Git class and parselog(), the heart of the script ###########################
class Git():
def __init__(self, workdir=None, gitdir=None):
self.gitcmd = ['git']
if workdir: self.gitcmd.extend(('--work-tree', workdir))
if gitdir : self.gitcmd.extend(('--git-dir', gitdir))
self.workdir, self.gitdir = self._repodirs()
def ls_files(self, pathlist=None):
return (normalize(_) for _ in self._run('ls-files --full-name', pathlist))
def is_dirty(self):
return bool(self._run('diff --no-ext-diff --quiet', output=False))
def log(self, merge=False, first_parent=False, commit_time=False, pathlist=None):
cmd = 'whatchanged --pretty={}'.format('%ct' if commit_time else '%at')
if merge: cmd += ' -m'
if first_parent: cmd += ' --first-parent'
return self._run(cmd, pathlist)
def _repodirs(self):
return (os.path.normpath(_) for _ in
self._run('rev-parse --show-toplevel --absolute-git-dir', check=True))
def _run(self, cmdstr, pathlist=None, output=True, check=False):
cmdlist = self.gitcmd + shlex.split(cmdstr)
if pathlist:
cmdlist.append('--')
cmdlist.extend(pathlist)
log.trace("Executing: %s", ' '.join(cmdlist))
if not output:
return subprocess.call(cmdlist)
if check:
try:
stdout = subprocess.check_output(cmdlist, universal_newlines=True)
return stdout.splitlines()
except subprocess.CalledProcessError as e:
raise self.Error(e.returncode, e.cmd, e.output, e.stderr)
self.proc = subprocess.Popen(cmdlist, stdout=subprocess.PIPE, universal_newlines=True)
return (_.strip() for _ in self.proc.stdout)
class Error(subprocess.CalledProcessError): pass
def parselog(filelist, dirlist, stats, git, merge=False, filterlist=None):
mtime = 0
for line in git.log(merge, args.first_parent, args.commit_time, filterlist):
stats['loglines'] += 1
# Blank line between Date and list of files
if not line: continue
# File line
if line[0] == ':': # Faster than line.startswith(':')
# If line describes a rename, linetok has three tokens, otherwise two
linetok = line.split('\t')
status = linetok[0]
file = linetok[-1]
# Handles non-ASCII chars and OS path separator
file = normalize(file)
if file in filelist:
stats['files'] -= 1
log.debug("%d\t%d\t%d\t%s\t%s",
stats['loglines'], stats['commits'], stats['files'],
isodate(mtime), file)
filelist.remove(file)
try:
touch(os.path.join(git.workdir, file), mtime, args.test)
stats['touches'] += 1
except Exception as e:
log.error("ERROR: %s", e)
stats['errors'] += 1
if args.dirs:
dirname = os.path.dirname(file)
if status[-1] in ('A', 'D') and dirname in dirlist:
log.debug("%d\t%d\t-\t%s\t%s",
stats['loglines'], stats['commits'],
isodate(mtime), "{}/".format(dirname or '.'))
dirlist.remove(dirname)
try:
touch(os.path.join(git.workdir, dirname), mtime, args.test)
stats['dirtouches'] += 1
except Exception as e:
log.error("ERROR: %s", e)
stats['direrrors'] += 1
# Date line
else:
stats['commits'] += 1
mtime = int(line)
# All files done?
if not stats['files']:
git.proc.terminate() # hackish, but does the job. Not needed anyway
return
# Main Logic ##################################################################
def main():
start = time.time() # yes, Wall time. CPU time is not realistic for users.
stats = {_: 0 for _ in ('loglines', 'commits', 'touches', 'errors', 'dirtouches', 'direrrors')}
# First things first: Where and Who are we?
try:
git = Git(args.workdir, args.gitdir)
except Git.Error as e:
# Not in a git repository, and git already informed user on stderr. So we just...
return e.returncode
# Do not work on dirty repositories, unless --force
if not args.force and git.is_dirty():
log.critical(
"ERROR: There are local changes in the working directory.\n"
"This could lead to undesirable results for modified files.\n"
"Please, commit your changes (or use --force) and try again.\n"
"Aborting")
return 1
# Get the files managed by git and build file and dir list to be processed
filelist = set()
dirlist = set()
if UPDATE_SYMLINKS and not args.skip_older_than:
filelist = set(git.ls_files(args.pathspec))
dirlist = set(os.path.dirname(_) for _ in filelist)
else:
for path in git.ls_files(args.pathspec):
fullpath = os.path.join(git.workdir, path)
# Symlink (to file, to dir or broken - git handles the same way)
if not UPDATE_SYMLINKS and os.path.islink(fullpath):
log.warning("WARNING: Skipping symlink, OS does not support update: %s", path)
continue
# skip files which are older than given threshold
if args.skip_older_than and start - os.path.getmtime(fullpath) > args.skip_older_than:
continue
# Always add them relative to worktree root
filelist.add(path)
dirlist.add(os.path.dirname(path))
stats['totalfiles'] = stats['files'] = len(filelist)
log.info("{0:,} files to be processed in work dir".format(stats['totalfiles']))
if not filelist:
# Nothing to do. Exit silently and without errors, just like git does
return
# Process the log until all files are 'touched'
log.debug("Line #\tLog #\tF.Left\tModification Time\tFile Name")
parselog(filelist, dirlist, stats, git, args.merge, args.pathspec)
# Missing files
if filelist:
# Try to find them in merge logs, if not done already
# (usually HUGE, thus MUCH slower!)
if args.missing and not args.merge:
filterlist = list(filelist)
for i in range(0, len(filterlist), STEPMISSING):
parselog(filelist, dirlist, stats, git,
merge=True, filterlist=filterlist[i:i+STEPMISSING])
# Still missing some?
for file in filelist:
log.warning("WARNING: not found in log: %s", file)
# Final statistics
# Suggestion: use git-log --before=mtime to brag about skipped log entries
log.info(
"Statistics:\n"
"{:13,.2f} seconds\n"
"{:13,} log lines processed\n"
"{:13,} commits evaluated"
"".format(time.time()-start, stats['loglines'], stats['commits']))
if args.dirs:
if stats['direrrors']: log.info("{:13,} directory update errors".format(stats['direrrors']))
log.info("{:13,} directories updated".format(stats['dirtouches']))
if stats['touches'] != stats['totalfiles']: log.info("{:13,} files".format(stats['totalfiles']))
if stats['files']: log.info("{:13,} files missing".format(stats['files']))
if stats['errors']: log.info("{:13,} file update errors".format(stats['errors']))
log.info("{:13,} files updated".format(stats['touches']))
if args.test:
log.info("TEST RUN - No files modified!")
args = parse_args()
log = setup_logging(args)
log.trace("Arguments: %s", args)
# UI done, it's show time!
try:
sys.exit(main())
except KeyboardInterrupt:
log.info("Aborting")
sys.exit(-1)
+426
View File
@@ -0,0 +1,426 @@
name: Build
on:
push:
tags: [ '*' ]
jobs:
web:
runs-on: ubuntu-latest
steps:
- name: Get current git tag
id: get_tag
uses: keeweb/get-git-tag@v3.0.2
with:
tagRegex: "^v(\\d+\\.\\d+\\.\\d+)$"
tagRegexGroup: 1
- name: Checkout
uses: actions/checkout@v2
with:
repository: keeweb/keeweb
ref: ${{ github.repository == 'keeweb/keeweb' && github.sha || 'develop' }}
- name: Upgrade Node.js
uses: actions/setup-node@v2
with:
node-version: '16'
registry-url: 'https://registry.npmjs.org'
- name: Install npm modules
run: npm ci
- name: Test
run: npm test
- name: Grunt
run: grunt
- name: Upload artifact
uses: actions/upload-artifact@v1
with:
name: KeeWeb-${{ steps.get_tag.outputs.tag }}.html
path: dist
- name: Write secrets
env:
VIRUS_TOTAL: ${{ secrets.VIRUS_TOTAL }}
run: |
mkdir keys
echo "$VIRUS_TOTAL" > keys/virus-total.json
- name: Check on VirusTotal
run: grunt virustotal
if: ${{ github.repository == 'keeweb/keeweb' }}
linux:
runs-on: ubuntu-latest
needs:
- web
steps:
- name: Get current git tag
id: get_tag
uses: keeweb/get-git-tag@v3.0.2
with:
tagRegex: "^v(\\d+\\.\\d+\\.\\d+)$"
tagRegexGroup: 1
- name: Checkout
uses: actions/checkout@v2
with:
repository: keeweb/keeweb
ref: ${{ github.repository == 'keeweb/keeweb' && github.sha || 'develop' }}
- name: Download artifact
uses: actions/download-artifact@v1
with:
name: KeeWeb-${{ steps.get_tag.outputs.tag }}.html
path: dist
- name: Write secrets
env:
PRIVATE_KEY: ${{ secrets.PRIVATE_KEY }}
KEEWEB_SIGN: ${{ secrets.KEEWEB_SIGN }}
run: |
mkdir keys
echo "$PRIVATE_KEY" > keys/private-key.pem
echo "$KEEWEB_SIGN" > keys/keeweb-sign.json
- name: Build in Docker
uses: ./.github/actions/linux-build
- name: Upload AppImage artifact
uses: actions/upload-artifact@v1
with:
name: KeeWeb-${{ steps.get_tag.outputs.tag }}.linux.AppImage
path: dist/desktop/KeeWeb-${{ steps.get_tag.outputs.tag }}.linux.AppImage
- name: Upload snap artifact
uses: actions/upload-artifact@v1
with:
name: KeeWeb-${{ steps.get_tag.outputs.tag }}.linux.snap
path: dist/desktop/KeeWeb-${{ steps.get_tag.outputs.tag }}.linux.snap
- name: Upload deb artifact
uses: actions/upload-artifact@v1
with:
name: KeeWeb-${{ steps.get_tag.outputs.tag }}.linux.x64.deb
path: dist/desktop/KeeWeb-${{ steps.get_tag.outputs.tag }}.linux.x64.deb
- name: Upload zip artifact
uses: actions/upload-artifact@v1
with:
name: KeeWeb-${{ steps.get_tag.outputs.tag }}.linux.x64.zip
path: dist/desktop/KeeWeb-${{ steps.get_tag.outputs.tag }}.linux.x64.zip
- name: Upload rpm artifact
uses: actions/upload-artifact@v1
with:
name: KeeWeb-${{ steps.get_tag.outputs.tag }}.linux.x86_64.rpm
path: dist/desktop/KeeWeb-${{ steps.get_tag.outputs.tag }}.linux.x86_64.rpm
darwin:
runs-on: macos-latest
needs:
- web
steps:
- name: Get current git tag
id: get_tag
uses: keeweb/get-git-tag@v3.0.2
with:
tagRegex: "^v(\\d+\\.\\d+\\.\\d+)$"
tagRegexGroup: 1
- name: Checkout
uses: actions/checkout@v2
with:
repository: keeweb/keeweb
ref: ${{ github.repository == 'keeweb/keeweb' && github.sha || 'develop' }}
- name: Download artifact
uses: actions/download-artifact@v1
with:
name: KeeWeb-${{ steps.get_tag.outputs.tag }}.html
path: dist
- name: Upgrade Node.js
uses: actions/setup-node@v2
with:
node-version: '16'
registry-url: 'https://registry.npmjs.org'
- name: Install npm modules
run: npm ci
- name: Install grunt
run: sudo npm i -g grunt-cli
- name: Write secrets
env:
CODESIGN: ${{ secrets.CODESIGN }}
APPLE_DEPLOY_PASSWORD: ${{ secrets.APPLE_DEPLOY_PASSWORD }}
APPLE_ID_USERNAME: ${{ secrets.APPLE_ID_USERNAME }}
APPLE_PROVISIONING_PROFILE: ${{ secrets.APPLE_PROVISIONING_PROFILE }}
run: |
mkdir keys
echo "$CODESIGN" > keys/codesign.json
xcrun altool --store-password-in-keychain-item "AC_PASSWORD" -u "$APPLE_ID_USERNAME" -p "$APPLE_DEPLOY_PASSWORD"
echo "$APPLE_PROVISIONING_PROFILE" | base64 -d > keys/keeweb.provisionprofile
- name: Import certificates
uses: keeweb/import-codesign-certs@v1
with:
p12-file-base64: ${{ secrets.APPLE_CERTIFICATE }}
p12-password: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
- name: Grunt
run: grunt --max-old-space-size=4096 desktop-darwin ${{ github.repository != 'keeweb/keeweb' && '--skip-sign' || '' }}
- name: Upload x64 dmg artifact
uses: actions/upload-artifact@v1
with:
name: KeeWeb-${{ steps.get_tag.outputs.tag }}.mac.x64.dmg
path: dist/desktop/KeeWeb-${{ steps.get_tag.outputs.tag }}.mac.x64.dmg
- name: Upload arm64 dmg artifact
uses: actions/upload-artifact@v1
with:
name: KeeWeb-${{ steps.get_tag.outputs.tag }}.mac.arm64.dmg
path: dist/desktop/KeeWeb-${{ steps.get_tag.outputs.tag }}.mac.arm64.dmg
win32:
runs-on: windows-latest
needs:
- web
steps:
- name: Get current git tag
id: get_tag
uses: keeweb/get-git-tag@v3.0.2
with:
tagRegex: "^v(\\d+\\.\\d+\\.\\d+)$"
tagRegexGroup: 1
- name: Checkout
uses: actions/checkout@v2
with:
repository: keeweb/keeweb
ref: ${{ github.repository == 'keeweb/keeweb' && github.sha || 'develop' }}
- name: Download artifact
uses: actions/download-artifact@v1
with:
name: KeeWeb-${{ steps.get_tag.outputs.tag }}.html
path: dist
- name: Upgrade Node.js
uses: actions/setup-node@v2
with:
node-version: '16'
registry-url: 'https://registry.npmjs.org'
- name: Install npm modules
run: npm ci
- name: Install grunt
run: npm i -g grunt-cli
- name: Write secrets
env:
CODESIGN: ${{ secrets.CODESIGN }}
MS_CODESIGN_PRIVATE_KEY_CLIENT: ${{ secrets.MS_CODESIGN_PRIVATE_KEY_CLIENT }}
MS_CODESIGN_PUBLIC_KEY_CLIENT: ${{ secrets.MS_CODESIGN_PUBLIC_KEY_CLIENT }}
MS_CODESIGN_PUBLIC_KEY_SERVER: ${{ secrets.MS_CODESIGN_PUBLIC_KEY_SERVER }}
run: |
mkdir keys
echo $Env:CODESIGN > keys/codesign.json
mkdir keys/code-signing
echo $Env:MS_CODESIGN_PRIVATE_KEY_CLIENT > keys/code-signing/private-key-client.pem
echo $Env:MS_CODESIGN_PUBLIC_KEY_CLIENT > keys/code-signing/public-key-client.pem
echo $Env:MS_CODESIGN_PUBLIC_KEY_SERVER > keys/code-signing/public-key-server.pem
- name: Grunt
run: grunt desktop-win32 ${{ github.repository != 'keeweb/keeweb' && '--skip-sign' || '' }}
- name: Upload ia32 exe artifact
uses: actions/upload-artifact@v1
with:
name: KeeWeb-${{ steps.get_tag.outputs.tag }}.win.ia32.exe
path: dist/desktop/KeeWeb-${{ steps.get_tag.outputs.tag }}.win.ia32.exe
- name: Upload ia32 zip artifact
uses: actions/upload-artifact@v1
with:
name: KeeWeb-${{ steps.get_tag.outputs.tag }}.win.ia32.zip
path: dist/desktop/KeeWeb-${{ steps.get_tag.outputs.tag }}.win.ia32.zip
- name: Upload x64 exe artifact
uses: actions/upload-artifact@v1
with:
name: KeeWeb-${{ steps.get_tag.outputs.tag }}.win.x64.exe
path: dist/desktop/KeeWeb-${{ steps.get_tag.outputs.tag }}.win.x64.exe
- name: Upload x64 zip artifact
uses: actions/upload-artifact@v1
with:
name: KeeWeb-${{ steps.get_tag.outputs.tag }}.win.x64.zip
path: dist/desktop/KeeWeb-${{ steps.get_tag.outputs.tag }}.win.x64.zip
- name: Upload arm64 exe artifact
uses: actions/upload-artifact@v1
with:
name: KeeWeb-${{ steps.get_tag.outputs.tag }}.win.arm64.exe
path: dist/desktop/KeeWeb-${{ steps.get_tag.outputs.tag }}.win.arm64.exe
- name: Upload arm64 zip artifact
uses: actions/upload-artifact@v1
with:
name: KeeWeb-${{ steps.get_tag.outputs.tag }}.win.arm64.zip
path: dist/desktop/KeeWeb-${{ steps.get_tag.outputs.tag }}.win.arm64.zip
publish:
runs-on: ubuntu-latest
needs:
- linux
- darwin
- win32
steps:
- name: Get current git tag
id: get_tag
uses: keeweb/get-git-tag@v3.0.2
with:
tagRegex: "^v(\\d+\\.\\d+\\.\\d+)$"
tagRegexGroup: 1
- name: Setup GCloud
uses: google-github-actions/setup-gcloud@master
with:
version: '285.0.0'
service_account_key: ${{ secrets.GCP_SA_KEY }}
export_default_credentials: true
- name: Checkout
uses: actions/checkout@v2
with:
repository: keeweb/keeweb
path: keeweb
ref: ${{ github.repository == 'keeweb/keeweb' && github.sha || 'develop' }}
- name: Upgrade Node.js
uses: actions/setup-node@v2
with:
node-version: '16'
registry-url: 'https://registry.npmjs.org'
- name: Install npm modules
working-directory: keeweb
run: npm ci
- name: Download html artifact
uses: actions/download-artifact@v1
with:
name: KeeWeb-${{ steps.get_tag.outputs.tag }}.html
path: html
- name: Download linux.AppImage artifact
uses: actions/download-artifact@v1
with:
name: KeeWeb-${{ steps.get_tag.outputs.tag }}.linux.AppImage
path: assets
- name: Download linux.snap artifact
uses: actions/download-artifact@v1
with:
name: KeeWeb-${{ steps.get_tag.outputs.tag }}.linux.snap
path: assets
- name: Download linux.deb artifact
uses: actions/download-artifact@v1
with:
name: KeeWeb-${{ steps.get_tag.outputs.tag }}.linux.x64.deb
path: assets
- name: Download linux.zip artifact
uses: actions/download-artifact@v1
with:
name: KeeWeb-${{ steps.get_tag.outputs.tag }}.linux.x64.zip
path: assets
- name: Download linux.rpm artifact
uses: actions/download-artifact@v1
with:
name: KeeWeb-${{ steps.get_tag.outputs.tag }}.linux.x86_64.rpm
path: assets
- name: Download darwin.x64.dmg artifact
uses: actions/download-artifact@v1
with:
name: KeeWeb-${{ steps.get_tag.outputs.tag }}.mac.x64.dmg
path: assets
- name: Download darwin.arm64.dmg artifact
uses: actions/download-artifact@v1
with:
name: KeeWeb-${{ steps.get_tag.outputs.tag }}.mac.arm64.dmg
path: assets
- name: Download win32.ia32.exe artifact
uses: actions/download-artifact@v1
with:
name: KeeWeb-${{ steps.get_tag.outputs.tag }}.win.ia32.exe
path: assets
- name: Download win32.ia32.zip artifact
uses: actions/download-artifact@v1
with:
name: KeeWeb-${{ steps.get_tag.outputs.tag }}.win.ia32.zip
path: assets
- name: Download win32.x64.exe artifact
uses: actions/download-artifact@v1
with:
name: KeeWeb-${{ steps.get_tag.outputs.tag }}.win.x64.exe
path: assets
- name: Download win32.x64.zip artifact
uses: actions/download-artifact@v1
with:
name: KeeWeb-${{ steps.get_tag.outputs.tag }}.win.x64.zip
path: assets
- name: Download win32.arm64.exe artifact
uses: actions/download-artifact@v1
with:
name: KeeWeb-${{ steps.get_tag.outputs.tag }}.win.arm64.exe
path: assets
- name: Download win32.arm64.zip artifact
uses: actions/download-artifact@v1
with:
name: KeeWeb-${{ steps.get_tag.outputs.tag }}.win.arm64.zip
path: assets
- name: Zip html
working-directory: html
run: zip -vr ../assets/KeeWeb-${{ steps.get_tag.outputs.tag }}.html.zip .
- name: Copy assets to dist
run: mkdir -p keeweb/dist/desktop && cp assets/* keeweb/dist/desktop
- name: Write secrets
env:
PRIVATE_KEY: ${{ secrets.PRIVATE_KEY }}
KEEWEB_SIGN: ${{ secrets.KEEWEB_SIGN }}
working-directory: keeweb
run: |
mkdir keys
echo "$PRIVATE_KEY" > keys/private-key.pem
echo "$KEEWEB_SIGN" > keys/keeweb-sign.json
- name: Grunt
working-directory: keeweb
run: grunt finish-release
- name: Copy signatures to assets
run: cp keeweb/dist/desktop/Verify.sign.sha256 assets
- name: Copy checksums to assets
run: cp keeweb/dist/desktop/Verify.sha256 assets
- name: Login to DockerHub Registry
env:
DOCKERHUB_ACCESS_TOKEN: ${{ secrets.DOCKERHUB_ACCESS_TOKEN }}
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
run: echo $DOCKERHUB_ACCESS_TOKEN | docker login -u $DOCKERHUB_USERNAME --password-stdin
- name: Copy dist to the Docker context
run: cp -r html keeweb/package/docker/dist
- name: Build the Docker image
working-directory: keeweb
run: docker build -t antelle/keeweb:latest -t antelle/keeweb:${{ steps.get_tag.outputs.tag }} package/docker
- name: Push the Docker image to dockerhub
if: ${{ github.repository == 'keeweb/keeweb' }}
run: docker push --all-tags antelle/keeweb
- name: Extract release notes
run: node util/extract-release-notes.js --version=${{ steps.get_tag.outputs.tag }} --output=tmp/release-body.md
working-directory: keeweb
- name: Publish GitHub release
uses: softprops/action-gh-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: v${{ steps.get_tag.outputs.tag }}
name: Desktop apps v${{ steps.get_tag.outputs.tag }}
files: assets/*
body_path: keeweb/tmp/release-body.md
- name: Checkout gh-pages
uses: actions/checkout@v2
with:
ref: gh-pages
path: gh-pages
fetch-depth: 0
- name: Commit dist to gh-pages
working-directory: gh-pages
run: |
git rm -r '*'
cp -r ../html/* .
mkdir -p .github/workflows
echo $GITHUB_SHA > build.txt
date >> build.txt
git add .
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git commit -am v${{ steps.get_tag.outputs.tag }}
- name: Push gh-pages
uses: keeweb/github-push-action@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
branch: gh-pages
directory: gh-pages
- name: Restore git mtime
working-directory: gh-pages
run: python3 ../keeweb/.github/actions/scripts/git-restore-mtime.py
- name: Sync the website
if: ${{ github.repository == 'keeweb/keeweb' }}
run: gsutil -m rsync -r -d -x "^\." gh-pages gs://app.keeweb.info/
- name: Purge CloudFlare cache
if: ${{ github.repository == 'keeweb/keeweb' }}
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
run: |
curl -sS -X POST "https://api.cloudflare.com/client/v4/zones/dbda8e7e454d23edb08d4bc3b3f6f872/purge_cache" \
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{"purge_everything":true}'
+4 -2
View File
@@ -3,7 +3,7 @@ misc.xml
.DS_Store
node_modules/
*.log
dist/
/dist/
tmp/
coverage/
keys
@@ -14,4 +14,6 @@ obj/
xcuserdata/
*.suo
.idea/
.vscode
.vscode/
*.iml
test/dist/
+8
View File
@@ -0,0 +1,8 @@
{
"tabWidth": 4,
"singleQuote": true,
"printWidth": 100,
"trailingComma": "none",
"quoteProps": "preserve",
"endOfLine": "auto"
}
+41 -5
View File
@@ -2,24 +2,41 @@
Thanks for taking the time to contribute! :gift:
There are different ways to help the project, you will find a summary here.
## Code of conduct
This project and everyone participating in it is governed by the [KeeWeb Code of Conduct](https://github.com/keeweb/keeweb/blob/master/.github/CODE_OF_CONDUCT.md#readme). By participating, you are expected to uphold this code. Please report unacceptable behavior to antelle.net@gmail.com.
This project and everyone participating in it is governed by the [KeeWeb Code of Conduct](https://github.com/keeweb/keeweb/blob/master/.github/CODE_OF_CONDUCT.md#readme).
By participating, you are expected to uphold this code. Please report unacceptable behavior to antelle.net@gmail.com.
## Issues
First, let's check if it's [already there](https://github.com/keeweb/keeweb/issues).
Perhaps, someone has already reported it?
[Click here](https://github.com/keeweb/keeweb/issues/new) to create a new issue.
[Click here](https://github.com/keeweb/keeweb/issues/new/choose) to create a new issue.
When creating issues, please answer some questions asked on that page.
They will help to understand, reproduce and fix your issue.
They will help to understand, reproduce, and fix your issue.
## Vulnerabilities
We would appreciate [responsible disclosure](https://en.wikipedia.org/wiki/Responsible_disclosure).
If you would like to report a vulnerability, the preferred way to do so is [contacting the developer directly](mailto:antelle.net@gmail.com).
## Questions, great ideas, etc...
You can [create an issue](https://github.com/keeweb/keeweb/issues/new) to discuss any question.
You can [create an issue](https://github.com/keeweb/keeweb/issues/new/choose) to discuss any topic.
Indeed, questions on that page are not applicable in this case.
## Development
We don't accept (and in foreseeable future, we won't accept) anyone as a project collaborator directly.
Instead, the code should be contributed via pull requests. To get started with development, take a look at these pages:
- [Architecture](https://github.com/keeweb/keeweb/wiki/Architecture)
- [Engineering](https://github.com/keeweb/keeweb/wiki/Engineering)
- [Unsupported Features](https://github.com/keeweb/keeweb/wiki/Unsupported%20Features)
- [Pull Request Guidelines](https://github.com/keeweb/keeweb/blob/master/.github/PULL_REQUEST_TEMPLATE.md#readme)
## Pull requests
Please follow [this guide](https://github.com/keeweb/keeweb/blob/master/.github/PULL_REQUEST_TEMPLATE.md#readme).
@@ -27,4 +44,23 @@ Please follow [this guide](https://github.com/keeweb/keeweb/blob/master/.github/
## Docs (Wiki pages)
KeeWeb has [Wiki pages](https://github.com/keeweb/keeweb/wiki), however it's not possible to contribute with pull requests.
If you would like to improve it, please [open an issue](https://github.com/keeweb/keeweb/issues/new) and submit your changes in Markdown format.
If you would like to improve it, please [open an issue](https://github.com/keeweb/keeweb/issues/new/choose) and submit your changes in Markdown format.
## Donations
There are two ways of donating:
- join as backer on [OpenCollective](https://opencollective.com/keeweb#support);
- sponsor the developer directly on [GitHub](https://github.com/sponsors/antelle).
Please note: donation does not imply any type of service contract.
## Translations
All KeeWeb translations are contributed by the community. To improve a translation or add a missing one,
join us on [OneSky](https://keeweb.oneskyapp.com).
## PR
We would be happy to support you if you decide to post, blog, or review the project,
or provide any other kind of PR. Please [contact the developer](mailto:antelle.net@gmail.com)
if you have anything to share. You can also poke us on [Twitter](https://twitter.com/kee_web).
+491 -269
View File
@@ -1,14 +1,17 @@
/* eslint-env node */
const fs = require('fs');
const fs = require('fs-extra');
const path = require('path');
const { execSync } = require('child_process');
const debug = require('debug');
const sass = require('node-sass');
const webpackConfig = require('./webpack.config');
const postCssReplaceFont = require('./build/util/postcss-replace-font');
const webpackConfig = require('./build/webpack.config');
const webpackConfigTest = require('./test/test.webpack.config');
const pkg = require('./package.json');
module.exports = function(grunt) {
debug.enable('electron-notarize');
module.exports = function (grunt) {
require('time-grunt')(grunt);
require('load-grunt-tasks')(grunt);
@@ -22,26 +25,72 @@ module.exports = function(grunt) {
const dt = date.toISOString().replace(/T.*/, '');
const year = date.getFullYear();
const minElectronVersionForUpdate = '4.0.1';
const zipCommentPlaceholderPart = 'zip_comment_placeholder_that_will_be_replaced_with_hash';
const zipCommentPlaceholder = zipCommentPlaceholderPart + '.'.repeat(512 - zipCommentPlaceholderPart.length);
const electronVersion = pkg.dependencies.electron.replace(/^\D/, '');
const skipSign = grunt.option('skip-sign');
const getCodeSignConfig = () =>
skipSign ? { identities: {} } : require('./keys/codesign.json');
let sha = grunt.option('commit-sha');
if (!sha) {
try {
sha = execSync('git rev-parse --short HEAD').toString('utf8').trim();
} catch (e) {
grunt.warn(
"Cannot get commit sha from git. It's recommended to build KeeWeb from a git repo " +
'because commit sha is displayed in the UI, however if you would like to build from a folder, ' +
'you can override what will be displayed in the UI with --commit-sha=xxx.'
);
}
}
grunt.log.writeln(`Building KeeWeb v${pkg.version} (${sha})`);
const webpackOptions = {
date,
beta: !!grunt.option('beta'),
sha,
appleTeamId: '3LE7JZ657W'
};
const windowsAppVersionString = {
CompanyName: 'KeeWeb',
FileDescription: pkg.description,
OriginalFilename: 'KeeWeb.exe',
ProductName: 'KeeWeb',
InternalName: 'KeeWeb'
};
const appdmgOptions = (arch) => ({
title: 'KeeWeb',
icon: 'graphics/icon.icns',
background: 'graphics/dmg-background.png',
'background-color': '#E0E6F9',
'icon-size': 80,
window: { size: { width: 658, height: 498 } },
contents: [
{ x: 438, y: 344, type: 'link', path: '/Applications' },
{
x: 192,
y: 344,
type: 'file',
path: `tmp/desktop/KeeWeb-darwin-${arch}/KeeWeb.app`
}
]
});
const linuxDependencies = [
'libappindicator1',
'libgconf-2-4',
'gnome-keyring',
'libxtst6',
'libx11-6',
'libatspi2.0-0'
];
grunt.initConfig({
gitinfo: {
branch: {
current: {
SHA: 'Current HEAD SHA',
shortSHA: 'Current HEAD short SHA',
name: 'Current branch name',
lastCommitTime: 'Last commit time'
}
}
},
noop: { noop: {} },
clean: {
dist: ['dist', 'tmp'],
desktop: ['tmp/desktop', 'dist/desktop'],
cordova: ['tmp/cordova', 'dist/cordova']
desktop: ['tmp/desktop', 'dist/desktop']
},
copy: {
html: {
@@ -49,9 +98,11 @@ module.exports = function(grunt) {
dest: 'tmp/index.html',
nonull: true
},
favicon: {
src: 'app/favicon.png',
dest: 'tmp/favicon.png',
'content-dist': {
cwd: 'app/content/',
src: '**',
dest: 'dist/',
expand: true,
nonull: true
},
icons: {
@@ -82,12 +133,10 @@ module.exports = function(grunt) {
expand: true,
nonull: true
},
fonts: {
src: 'node_modules/font-awesome/fonts/fontawesome-webfont.*',
dest: 'tmp/fonts/',
nonull: true,
expand: true,
flatten: true
'desktop-html': {
src: 'dist/index.html',
dest: 'tmp/desktop/app/index.html',
nonull: true
},
'desktop-app-content': {
cwd: 'desktop/',
@@ -96,38 +145,20 @@ module.exports = function(grunt) {
expand: true,
nonull: true
},
'desktop-update': {
cwd: 'tmp/desktop/KeeWeb-darwin-x64/KeeWeb.app/Contents/Resources/',
src: 'app.asar',
dest: 'tmp/desktop/update/',
expand: true,
nonull: true
},
'desktop-update-helper': {
src: ['helper/darwin/KeeWebHelper', 'helper/win32/KeeWebHelper.exe'],
dest: 'tmp/desktop/update/',
nonull: true
},
'desktop-windows-helper-ia32': {
src: 'helper/win32/KeeWebHelper.exe',
dest: 'tmp/desktop/KeeWeb-win32-ia32/Resources/',
nonull: true
},
'desktop-windows-helper-x64': {
src: 'helper/win32/KeeWebHelper.exe',
dest: 'tmp/desktop/KeeWeb-win32-x64/Resources/',
nonull: true
},
'desktop-darwin-helper-x64': {
src: 'helper/darwin/KeeWebHelper',
dest: 'tmp/desktop/KeeWeb-darwin-x64/KeeWeb.app/Contents/Resources/',
nonull: true,
options: { mode: '0755' }
},
'desktop-darwin-installer': {
cwd: 'package/osx/KeeWeb Installer.app',
dest: 'tmp/desktop/KeeWeb-darwin-x64/KeeWeb.app/Contents/Installer/KeeWeb Installer.app',
'desktop-darwin-installer-helper-x64': {
cwd: 'tmp/desktop/KeeWeb Installer.app',
src: '**',
dest:
'tmp/desktop/KeeWeb-darwin-x64/KeeWeb.app/Contents/Installer/KeeWeb Installer.app',
expand: true,
nonull: true,
options: { mode: true }
},
'desktop-darwin-installer-helper-arm64': {
cwd: 'tmp/desktop/KeeWeb Installer.app',
src: '**',
dest:
'tmp/desktop/KeeWeb-darwin-arm64/KeeWeb.app/Contents/Installer/KeeWeb Installer.app',
expand: true,
nonull: true,
options: { mode: true }
@@ -141,36 +172,111 @@ module.exports = function(grunt) {
src: 'tmp/desktop/KeeWeb.win.ia32.exe',
dest: `dist/desktop/KeeWeb-${pkg.version}.win.ia32.exe`,
nonull: true
},
'desktop-win32-dist-arm64': {
src: 'tmp/desktop/KeeWeb.win.arm64.exe',
dest: `dist/desktop/KeeWeb-${pkg.version}.win.arm64.exe`,
nonull: true
},
'native-modules-darwin-x64': {
src: 'node_modules/@keeweb/keeweb-native-modules/*-darwin-x64.node',
dest: 'tmp/desktop/KeeWeb-darwin-x64/KeeWeb.app/Contents/Resources/',
nonull: true
},
'native-modules-darwin-arm64': {
src: 'node_modules/@keeweb/keeweb-native-modules/*-darwin-arm64.node',
dest: 'tmp/desktop/KeeWeb-darwin-arm64/KeeWeb.app/Contents/Resources/',
nonull: true
},
'native-modules-win32-x64': {
src: 'node_modules/@keeweb/keeweb-native-modules/*-win32-x64.node',
dest: 'tmp/desktop/KeeWeb-win32-x64/resources/',
nonull: true
},
'native-modules-win32-ia32': {
src: 'node_modules/@keeweb/keeweb-native-modules/*-win32-ia32.node',
dest: 'tmp/desktop/KeeWeb-win32-ia32/resources/',
nonull: true
},
'native-modules-win32-arm64': {
src: 'node_modules/@keeweb/keeweb-native-modules/*-win32-arm64.node',
dest: 'tmp/desktop/KeeWeb-win32-arm64/resources/',
nonull: true
},
'native-modules-linux-x64': {
src: 'node_modules/@keeweb/keeweb-native-modules/*-linux-x64.node',
dest: 'tmp/desktop/keeweb-linux-x64/resources/',
nonull: true
},
'electron-builder-dist-linux-rpm': {
src: `tmp/desktop/electron-builder/KeeWeb-${pkg.version}.x86_64.rpm`,
dest: `dist/desktop/KeeWeb-${pkg.version}.linux.x86_64.rpm`,
nonull: true
},
'electron-builder-dist-linux-snap': {
src: `tmp/desktop/electron-builder/KeeWeb_${pkg.version}_amd64.snap`,
dest: `dist/desktop/KeeWeb-${pkg.version}.linux.snap`,
nonull: true
},
'electron-builder-dist-linux-appimage': {
src: `tmp/desktop/electron-builder/keeweb-${pkg.version}.AppImage`,
dest: `dist/desktop/KeeWeb-${pkg.version}.linux.AppImage`,
nonull: true
},
'darwin-installer-icon': {
src: 'graphics/icon.icns',
dest: 'tmp/desktop/KeeWeb Installer.app/Contents/Resources/applet.icns',
nonull: true
},
'native-messaging-host-darwin-x64': {
src:
'node_modules/@keeweb/keeweb-native-messaging-host/darwin-x64/keeweb-native-messaging-host',
dest:
'tmp/desktop/KeeWeb-darwin-x64/KeeWeb.app/Contents/MacOS/util/keeweb-native-messaging-host',
nonull: true,
options: { mode: '0755' }
},
'native-messaging-host-darwin-arm64': {
src:
'node_modules/@keeweb/keeweb-native-messaging-host/darwin-arm64/keeweb-native-messaging-host',
dest:
'tmp/desktop/KeeWeb-darwin-arm64/KeeWeb.app/Contents/MacOS/util/keeweb-native-messaging-host',
nonull: true,
options: { mode: '0755' }
},
'native-messaging-host-linux-x64': {
src:
'node_modules/@keeweb/keeweb-native-messaging-host/linux-x64/keeweb-native-messaging-host',
dest: 'tmp/desktop/keeweb-linux-x64/keeweb-native-messaging-host',
nonull: true,
options: { mode: '0755' }
},
'native-messaging-host-win32-x64': {
src:
'node_modules/@keeweb/keeweb-native-messaging-host/win32-x64/keeweb-native-messaging-host.exe',
dest: 'tmp/desktop/KeeWeb-win32-x64/keeweb-native-messaging-host.exe',
nonull: true
},
'native-messaging-host-win32-ia32': {
src:
'node_modules/@keeweb/keeweb-native-messaging-host/win32-ia32/keeweb-native-messaging-host.exe',
dest: 'tmp/desktop/KeeWeb-win32-ia32/keeweb-native-messaging-host.exe',
nonull: true
},
'native-messaging-host-win32-arm64': {
src:
'node_modules/@keeweb/keeweb-native-messaging-host/win32-arm64/keeweb-native-messaging-host.exe',
dest: 'tmp/desktop/KeeWeb-win32-arm64/keeweb-native-messaging-host.exe',
nonull: true
}
},
eslint: {
app: ['app/scripts/**/*.js'],
desktop: ['desktop/**/*.js', '!desktop/node_modules/**'],
grunt: ['Gruntfile.js', 'grunt/**/*.js']
},
sass: {
options: {
sourceMap: false,
includePaths: ['./node_modules'],
implementation: sass
},
dist: {
files: {
'tmp/css/main.css': 'app/styles/main.scss'
}
}
},
postcss: {
options: {
processors: [
postCssReplaceFont,
require('cssnano')({discardComments: {removeAll: true}})
]
},
dist: {
src: 'tmp/css/main.css',
dest: 'tmp/css/main.css'
}
build: ['Gruntfile.js', 'grunt.*.js', 'build/**/*.js', 'webpack.config.js'],
plugins: ['plugins/**/*.js'],
util: ['util/**/*.js'],
installer: ['package/osx/installer.js']
},
inline: {
app: {
@@ -178,6 +284,19 @@ module.exports = function(grunt) {
dest: 'tmp/app.html'
}
},
'csp-hashes': {
options: {
algo: 'sha512',
expected: {
style: 1,
script: 1
}
},
app: {
src: 'tmp/app.html',
dest: 'dist/index.html'
}
},
htmlmin: {
options: {
removeComments: true,
@@ -185,45 +304,65 @@ module.exports = function(grunt) {
},
app: {
files: {
'dist/index.html': 'tmp/app.html'
'tmp/app.html': 'tmp/app.html'
}
}
},
'string-replace': {
manifest: {
'update-manifest': {
options: {
replacements: [
{ pattern: '# YYYY-MM-DD:v0.0.0', replacement: '# ' + dt + ':v' + pkg.version },
{ pattern: '# updmin:v0.0.0', replacement: '# updmin:v' + minElectronVersionForUpdate }
{
pattern: /"version":\s*".*?"/,
replacement: `"version": "${pkg.version}"`
},
{
pattern: /"date":\s*".*?"/,
replacement: `"date": "${dt}"`
}
]
},
files: { 'dist/manifest.appcache': 'app/manifest.appcache' }
files: { 'dist/update.json': 'app/update.json' }
},
'manifest-html': {
options: { replacements: [{ pattern: '<html', replacement: '<html manifest="manifest.appcache"' }] },
files: { 'dist/index.html': 'dist/index.html' }
},
'desktop-html': {
options: { replacements: [{ pattern: ' manifest="manifest.appcache"', replacement: '' }] },
files: { 'tmp/desktop/app/index.html': 'dist/index.html' }
'service-worker': {
options: { replacements: [{ pattern: '0.0.0', replacement: pkg.version }] },
files: { 'dist/service-worker.js': 'app/service-worker.js' }
},
'desktop-public-key': {
options: { replacements: [{ pattern: '\'@@PUBLIC_KEY_CONTENT\'', replacement:
'`' + fs.readFileSync('app/resources/public-key.pem', {encoding: 'utf8'}).trim() + '`' }] },
options: {
replacements: [
{
pattern: "'@@PUBLIC_KEY_CONTENT'",
replacement:
'`' +
fs
.readFileSync('app/resources/public-key.pem', {
encoding: 'utf8'
})
.trim() +
'`'
}
]
},
files: { 'tmp/desktop/app/main.js': 'desktop/main.js' }
},
'cordova-html': {
options: { replacements: [{ pattern: '<script', replacement: '<script src="cordova.js"></script><script' }] },
files: { 'tmp/cordova/app/index.html': 'dist/index.html' }
}
},
webpack: {
js: webpackConfig.config(grunt)
app: webpackConfig.config(webpackOptions),
test: webpackConfigTest
},
'webpack-dev-server': {
options: {
webpack: webpackConfig.devServerConfig(grunt),
publicPath: '/tmp/js',
webpack: webpackConfig.config({
...webpackOptions,
mode: 'development',
sha: 'dev'
}),
publicPath: '/',
contentBase: [
path.resolve(__dirname, 'tmp'),
path.resolve(__dirname, 'app/content')
],
progress: false
},
js: {
@@ -231,105 +370,130 @@ module.exports = function(grunt) {
port: 8085
}
},
uglify: {
options: {
preserveComments: false
},
app: {
files: { 'tmp/js/app.js': ['tmp/js/app.js'] }
},
vendor: {
options: {
mangle: false,
compress: false
},
files: { 'tmp/js/vendor.js': ['tmp/js/vendor.js'] }
}
},
watch: {
options: {
interrupt: true,
debounceDelay: 500
},
styles: {
files: 'app/styles/**/*.scss',
tasks: ['sass']
},
indexhtml: {
files: 'app/index.html',
tasks: ['copy:html']
}
},
electron: {
options: {
name: 'KeeWeb',
dir: 'tmp/desktop/app',
out: 'tmp/desktop',
electronVersion: electronVersion,
electronVersion,
overwrite: true,
asar: true,
'appCopyright': `Copyright © ${year} Antelle`,
'appVersion': pkg.version,
'buildVersion': '<%= gitinfo.local.branch.current.shortSHA %>'
appCopyright: `Copyright © ${year} Antelle`,
appVersion: pkg.version,
buildVersion: sha
},
linux: {
options: {
name: 'keeweb',
platform: 'linux',
arch: ['x64', 'ia32'],
arch: 'x64',
icon: 'graphics/icon.ico'
}
},
darwin: {
'darwin-x64': {
options: {
platform: 'darwin',
arch: ['x64'],
arch: 'x64',
icon: 'graphics/icon.icns',
'appBundleId': 'net.antelle.keeweb',
'appCategoryType': 'public.app-category.productivity',
'extendInfo': 'package/osx/extend.plist'
appBundleId: 'net.antelle.keeweb',
appCategoryType: 'public.app-category.productivity',
extendInfo: 'package/osx/extend.plist'
}
},
win32: {
'darwin-arm64': {
options: {
platform: 'darwin',
arch: 'arm64',
icon: 'graphics/icon.icns',
appBundleId: 'net.antelle.keeweb',
appCategoryType: 'public.app-category.productivity',
extendInfo: 'package/osx/extend.plist'
}
},
'win32-x64': {
options: {
platform: 'win32',
arch: ['ia32', 'x64'],
arch: 'x64',
icon: 'graphics/icon.ico',
'buildVersion': pkg.version,
'version-string': {
'CompanyName': 'KeeWeb',
'FileDescription': pkg.description,
'OriginalFilename': 'KeeWeb.exe',
'ProductName': 'KeeWeb',
'InternalName': 'KeeWeb'
buildVersion: pkg.version,
'version-string': windowsAppVersionString
}
},
'win32-ia32': {
options: {
platform: 'win32',
arch: 'ia32',
icon: 'graphics/icon.ico',
buildVersion: pkg.version,
'version-string': windowsAppVersionString
}
},
'win32-arm64': {
options: {
platform: 'win32',
arch: 'arm64',
icon: 'graphics/icon.ico',
buildVersion: pkg.version,
'version-string': windowsAppVersionString
}
}
},
'electron-builder': {
linux: {
options: {
publish: 'never',
targets: 'linux',
prepackaged: 'tmp/desktop/keeweb-linux-x64',
config: {
appId: 'net.antelle.keeweb',
productName: 'keeweb',
copyright: `Copyright © ${year} Antelle`,
directories: {
output: 'tmp/desktop/electron-builder',
app: 'desktop',
buildResources: 'graphics'
},
fileAssociations: {
ext: 'kdbx',
name: 'KeePass 2 database',
mimeType: 'application/x-keepass2'
},
linux: {
target: ['AppImage', 'snap', 'rpm'],
category: 'Utility'
},
rpm: {
// depends: linuxDependencies
},
snap: {
stagePackages: linuxDependencies
}
}
}
}
},
codesign: {
app: {
options: {
identity: 'app',
deep: true
},
src: ['tmp/desktop/KeeWeb-darwin-x64/KeeWeb.app']
'electron-patch': {
'win32-x64': 'tmp/desktop/KeeWeb-win32-x64/KeeWeb.exe',
'win32-ia32': 'tmp/desktop/KeeWeb-win32-ia32/KeeWeb.exe',
'win32-arm64': 'tmp/desktop/KeeWeb-win32-arm64/KeeWeb.exe',
'darwin-x64': 'tmp/desktop/KeeWeb-darwin-x64/KeeWeb.app',
'darwin-arm64': 'tmp/desktop/KeeWeb-darwin-arm64/KeeWeb.app',
'linux': 'tmp/desktop/KeeWeb-linux-x64/keeweb'
},
osacompile: {
options: {
language: 'JavaScript'
},
dmg: {
options: {
identity: 'app'
},
src: [`dist/desktop/KeeWeb-${pkg.version}.mac.dmg`]
installer: {
files: {
'tmp/desktop/KeeWeb Installer.app': 'package/osx/installer.js'
}
}
},
compress: {
options: {
level: 6
},
'desktop-update': {
options: { archive: 'dist/desktop/UpdateDesktop.zip', comment: zipCommentPlaceholder },
files: [
{ cwd: 'tmp/desktop/update', src: '**', expand: true, nonull: true }
]
},
'win32-x64': {
options: { archive: `dist/desktop/KeeWeb-${pkg.version}.win.x64.zip` },
files: [{ cwd: 'tmp/desktop/KeeWeb-win32-x64', src: '**', expand: true }]
@@ -338,39 +502,33 @@ module.exports = function(grunt) {
options: { archive: `dist/desktop/KeeWeb-${pkg.version}.win.ia32.zip` },
files: [{ cwd: 'tmp/desktop/KeeWeb-win32-ia32', src: '**', expand: true }]
},
'win32-arm64': {
options: { archive: `dist/desktop/KeeWeb-${pkg.version}.win.arm64.zip` },
files: [{ cwd: 'tmp/desktop/KeeWeb-win32-arm64', src: '**', expand: true }]
},
'linux-x64': {
options: { archive: `dist/desktop/KeeWeb-${pkg.version}.linux.x64.zip` },
files: [{ cwd: 'tmp/desktop/KeeWeb-linux-x64', src: '**', expand: true },
{ cwd: 'graphics', src: '128x128.png', nonull: true, expand: true }]
},
'linux-ia32': {
options: { archive: `dist/desktop/KeeWeb-${pkg.version}.linux.ia32.zip` },
files: [{ cwd: 'tmp/desktop/KeeWeb-linux-ia32', src: '**', expand: true },
{ cwd: 'graphics', src: '128x128.png', nonull: true, expand: true }]
files: [
{ cwd: 'tmp/desktop/keeweb-linux-x64', src: '**', expand: true },
{ cwd: 'graphics', src: '128x128.png', nonull: true, expand: true }
]
}
},
appdmg: {
options: {
title: 'KeeWeb',
icon: 'graphics/icon.icns',
background: 'graphics/background.png',
'background-color': '#E0E6F9',
'icon-size': 80,
window: { size: { width: 658, height: 498 } },
contents: [
{ x: 438, y: 344, type: 'link', path: '/Applications' },
{ x: 192, y: 344, type: 'file', path: 'tmp/desktop/KeeWeb-darwin-x64/KeeWeb.app' }
]
x64: {
options: appdmgOptions('x64'),
dest: `dist/desktop/KeeWeb-${pkg.version}.mac.x64.dmg`
},
app: {
dest: `dist/desktop/KeeWeb-${pkg.version}.mac.dmg`
arm64: {
options: appdmgOptions('arm64'),
dest: `dist/desktop/KeeWeb-${pkg.version}.mac.arm64.dmg`
}
},
nsis: {
options: {
vars: {
version: pkg.version,
rev: function() { return grunt.config.get('gitinfo.local.branch.current.shortSHA'); },
rev: sha,
homepage: pkg.homepage
}
},
@@ -401,6 +559,28 @@ module.exports = function(grunt) {
arch: 'ia32',
output: 'tmp/desktop/KeeWeb-win32-ia32/uninst.exe'
}
},
'win32-arm64': {
options: {
installScript: 'package/nsis/main.nsi',
arch: 'arm64',
output: 'tmp/desktop/KeeWeb.win.arm64.exe'
}
},
'win32-un-arm64': {
options: {
installScript: 'package/nsis/main-un.nsi',
arch: 'arm64',
output: 'tmp/desktop/KeeWeb-win32-arm64/uninst.exe'
}
}
},
chmod: {
'linux-desktop-x64': {
options: {
mode: '4755'
},
src: ['tmp/desktop/keeweb-linux-x64/chrome-sandbox']
}
},
deb: {
@@ -412,7 +592,7 @@ module.exports = function(grunt) {
description: pkg.description,
author: pkg.author,
homepage: pkg.homepage,
rev: function() { return grunt.config.get('gitinfo.local.branch.current.shortSHA'); }
rev: sha
}
},
'linux-x64': {
@@ -422,7 +602,7 @@ module.exports = function(grunt) {
pkgName: `KeeWeb-${pkg.version}.linux.x64.deb`,
targetDir: 'dist/desktop',
appName: 'KeeWeb',
depends: 'libappindicator1, libgconf2-4',
depends: linuxDependencies.join(', '),
scripts: {
postinst: 'package/deb/scripts/postinst'
}
@@ -430,82 +610,86 @@ module.exports = function(grunt) {
},
files: [
{ cwd: 'package/deb/usr', src: '**', dest: '/usr', expand: true, nonull: true },
{ cwd: 'tmp/desktop/KeeWeb-linux-x64/', src: '**', dest: '/opt/keeweb-desktop', expand: true, nonull: true },
{ src: 'graphics/128x128.png', dest: '/usr/share/icons/hicolor/128x128/apps/keeweb.png', nonull: true }
{
cwd: 'tmp/desktop/keeweb-linux-x64/',
src: '**',
dest: '/usr/share/keeweb-desktop',
expand: true,
nonull: true
},
{
src: 'graphics/128x128.png',
dest: '/usr/share/icons/hicolor/128x128/apps/keeweb.png',
nonull: true
}
]
}
},
'osx-sign': {
options: {
get identity() {
return getCodeSignConfig().identities.app;
},
hardenedRuntime: true,
entitlements: 'package/osx/entitlements.plist',
'entitlements-inherit': 'package/osx/entitlements-inherit.plist',
'gatekeeper-assess': false
},
'linux-ia32': {
'desktop-x64': {
options: {
info: {
arch: 'i386',
pkgName: `KeeWeb-${pkg.version}.linux.ia32.deb`,
targetDir: 'dist/desktop',
appName: 'KeeWeb',
depends: 'libappindicator1, libgconf2-4',
scripts: {
postinst: 'package/deb/scripts/postinst'
}
}
'provisioning-profile': './keys/keeweb.provisionprofile'
},
files: [
{ cwd: 'package/deb/usr', src: '**', dest: '/usr', expand: true, nonull: true },
{ cwd: 'tmp/desktop/KeeWeb-linux-ia32/', src: '**', dest: '/opt/keeweb-desktop', expand: true, nonull: true },
{ src: 'graphics/128x128.png', dest: '/usr/share/icons/hicolor/128x128/apps/keeweb.png', nonull: true }
]
src: 'tmp/desktop/KeeWeb-darwin-x64/KeeWeb.app'
},
'desktop-arm64': {
options: {
'provisioning-profile': './keys/keeweb.provisionprofile'
},
src: 'tmp/desktop/KeeWeb-darwin-arm64/KeeWeb.app'
},
'installer': {
src: 'tmp/desktop/KeeWeb Installer.app'
}
},
'sign-archive': {
'desktop-update': {
options: {
file: 'dist/desktop/UpdateDesktop.zip',
signature: zipCommentPlaceholder
}
}
},
'sign-desktop-files': {
'desktop-update': {
options: {
path: 'tmp/desktop/update'
}
}
},
'validate-desktop-update': {
desktop: {
options: {
file: 'dist/desktop/UpdateDesktop.zip',
expected: [
'app.asar',
'helper/darwin/KeeWebHelper',
'helper/win32/KeeWebHelper.exe'
],
expectedCount: 7,
publicKey: 'app/resources/public-key.pem'
}
}
},
'sign-html': {
'app': {
options: {
file: 'dist/index.html',
skip: grunt.option('skip-sign')
notarize: {
options: {
appBundleId: 'net.antelle.keeweb',
get appleId() {
return getCodeSignConfig().appleId;
},
appleIdPassword: '@keychain:AC_PASSWORD',
get ascProvider() {
return getCodeSignConfig().teamId;
}
},
'desktop-x64': {
src: 'tmp/desktop/KeeWeb-darwin-x64/KeeWeb.app'
},
'desktop-arm64': {
src: 'tmp/desktop/KeeWeb-darwin-arm64/KeeWeb.app'
}
},
'sign-exe': {
options: {
spc: 'keys/keeweb.spc',
key: '01',
algo: 'sha256',
url: pkg.homepage
url: pkg.homepage,
get windows() {
return getCodeSignConfig().windows;
},
get certHash() {
return getCodeSignConfig().microsoftCertHash;
}
},
'win32-build-x64': {
options: {
files: {
'tmp/desktop/KeeWeb-win32-x64/KeeWeb.exe': 'KeeWeb',
'tmp/desktop/KeeWeb-win32-x64/keeweb-native-messaging-host.exe':
'KeeWeb Native Messaging Host',
'tmp/desktop/KeeWeb-win32-x64/ffmpeg.dll': '',
'tmp/desktop/KeeWeb-win32-x64/libEGL.dll': 'ANGLE libEGL Dynamic Link Library',
'tmp/desktop/KeeWeb-win32-x64/libGLESv2.dll': 'ANGLE libGLESv2 Dynamic Link Library',
'tmp/desktop/KeeWeb-win32-x64/osmesa.dll': ''
'tmp/desktop/KeeWeb-win32-x64/libEGL.dll':
'ANGLE libEGL Dynamic Link Library',
'tmp/desktop/KeeWeb-win32-x64/libGLESv2.dll':
'ANGLE libGLESv2 Dynamic Link Library'
}
}
},
@@ -513,10 +697,27 @@ module.exports = function(grunt) {
options: {
files: {
'tmp/desktop/KeeWeb-win32-ia32/KeeWeb.exe': 'KeeWeb',
'tmp/desktop/KeeWeb-win32-ia32/keeweb-native-messaging-host.exe':
'KeeWeb Native Messaging Host',
'tmp/desktop/KeeWeb-win32-ia32/ffmpeg.dll': '',
'tmp/desktop/KeeWeb-win32-ia32/libEGL.dll': 'ANGLE libEGL Dynamic Link Library',
'tmp/desktop/KeeWeb-win32-ia32/libGLESv2.dll': 'ANGLE libGLESv2 Dynamic Link Library',
'tmp/desktop/KeeWeb-win32-ia32/osmesa.dll': ''
'tmp/desktop/KeeWeb-win32-ia32/libEGL.dll':
'ANGLE libEGL Dynamic Link Library',
'tmp/desktop/KeeWeb-win32-ia32/libGLESv2.dll':
'ANGLE libGLESv2 Dynamic Link Library'
}
}
},
'win32-build-arm64': {
options: {
files: {
'tmp/desktop/KeeWeb-win32-arm64/KeeWeb.exe': 'KeeWeb',
'tmp/desktop/KeeWeb-win32-arm64/keeweb-native-messaging-host.exe':
'KeeWeb Native Messaging Host',
'tmp/desktop/KeeWeb-win32-arm64/ffmpeg.dll': '',
'tmp/desktop/KeeWeb-win32-arm64/libEGL.dll':
'ANGLE libEGL Dynamic Link Library',
'tmp/desktop/KeeWeb-win32-arm64/libGLESv2.dll':
'ANGLE libGLESv2 Dynamic Link Library'
}
}
},
@@ -534,6 +735,13 @@ module.exports = function(grunt) {
}
}
},
'win32-uninst-arm64': {
options: {
files: {
'tmp/desktop/KeeWeb-win32-arm64/uninst.exe': 'KeeWeb Uninstaller'
}
}
},
'win32-installer-x64': {
options: {
files: {
@@ -547,26 +755,40 @@ module.exports = function(grunt) {
'tmp/desktop/KeeWeb.win.ia32.exe': 'KeeWeb Setup'
}
}
},
'win32-installer-arm64': {
options: {
files: {
'tmp/desktop/KeeWeb.win.arm64.exe': 'KeeWeb Setup'
}
}
}
},
'concurrent': {
options: {
logConcurrentOutput: true
},
'dev-server': [
'watch:styles',
'webpack-dev-server'
]
},
'sign-dist': {
'dist': {
dist: {
options: {
sign: 'dist/desktop/Verify.sign.sha256'
},
files: {
'dist/desktop/Verify.sha256': ['dist/desktop/KeeWeb-*', 'dist/desktop/UpdateDesktop.zip']
'dist/desktop/Verify.sha256': ['dist/desktop/KeeWeb-*']
}
}
},
'run-test': {
options: {
headless: true
},
default: 'test/runner.html'
},
virustotal: {
options: {
prefix: `keeweb.v${pkg.version}-${sha}.`,
timeout: 10 * 60 * 1000,
get apiKey() {
return require('./keys/virus-total.json').apiKey;
}
},
html: 'dist/index.html'
}
});
};
+1 -1
View File
@@ -1,6 +1,6 @@
MIT License
Copyright (c) 2019 Antelle
Copyright (c) 2021 Antelle https://antelle.net
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
+41 -20
View File
@@ -5,22 +5,22 @@ The app can run either in browser, or as a desktop app.
![screenshot](img/screenshot.png)
# Quick Links
## Quick Links
Apps: [Web](https://app.keeweb.info/), [Desktop](https://github.com/keeweb/keeweb/releases/latest)
Timeline: [Release Notes](release-notes.md), [TODO](https://github.com/keeweb/keeweb/wiki/TODO)
On one page: [Features](https://keeweb.info/#features), [FAQ](https://github.com/keeweb/keeweb/wiki/FAQ)
Website: [keeweb.info](https://keeweb.info)
Twitter: [kee_web](https://twitter.com/kee_web)
Donate: [OpenCollective](https://opencollective.com/keeweb#support), [GitHub](https://github.com/sponsors/antelle)
# Status
## Status
The app is already rather stable, so basic stuff should work.
Project roadmap with planned features and approximate schedule is on [TODO](https://github.com/keeweb/keeweb/wiki/TODO) page.
The app is quite stable now. Basic stuff, as well as more advanced operations, should be rather reliable.
# Self-hosting
## Self-hosting
Everything you need to host this app on your server is any static file server. The app is a single HTML file + cache manifest (optionally; for offline access).
Everything you need to host this app on your server is any static file server. The app is a single HTML file + a service worker (optionally; for offline access).
You can download the latest distribution files from [gh-pages](https://github.com/keeweb/keeweb/archive/gh-pages.zip) branch.
If you are using Docker:
@@ -33,47 +33,68 @@ docker run --name keeweb -d -p 443:443 -p 80:80 -v $EXT_DIR:/etc/nginx/external/
To make Dropbox work in your self-hosted app, [go to this Wiki page](https://github.com/keeweb/keeweb/wiki/Dropbox-and-GDrive).
# Building
## Building
The easiest way to clone all KeeWeb repos is:
```bash
curl https://raw.githubusercontent.com/keeweb/keeweb/develop/dev-env.sh | bash -
```
The app can be built with grunt: `grunt` (html file will be in `dist/`).
Desktop apps are built with `grunt desktop`. This works only in macOS as it builds dmg; requires wine.
Also, a hardware token is required.
To run Electron app without building an installer, build the app with `grunt` and start it this way:
The app can be built with grunt: `grunt` (html files will be in `dist/`).
Desktop apps are built with `grunt desktop`. This requires some magic and currently works only on CI,
you can find more details in [the GitHub Actions workflow](.github/workflows/build.yaml).
To run the desktop (electron) app without building an installer, build the app with `grunt` and start it this way:
```bash
grunt dev
npm run-script electron
npm run dev
npm run electron
```
For debug build:
1. run `grunt dev`
2. open `http://localhost:8085/tmp`
1. run `npm run dev`
2. open `http://localhost:8085`
# Contributing
To build desktop apps, use these goals, the result can be found in `tmp`:
```
npm run dev-desktop-macos
npm run dev-desktop-windows
npm run dev-desktop-linux
```
## Contributing
Please read contribution guidelines [for pull requests](.github/PULL_REQUEST_TEMPLATE.md).
Here's a [list of issues](https://github.com/keeweb/keeweb/labels/help%20wanted) where your help would be very welcome.
Also you can help by [translating KeeWeb](https://keeweb.oneskyapp.com) to your language.
### Important notes for pull requests
Other ways of contribution can be found [on this page](CONTRIBUTING.md).
#### Important notes for pull requests
- please branch from `develop`, not `master`
- don't edit translation files except base.json, they will be replaced
# Donations
## Donations
KeeWeb is not free to develop. It takes time, requires paid code signing certificates and domains.
You can help the project or say "thank you" with this button:
[<img src="img/paypal-donate.png" alt="Donate with PayPal" width="100">](https://www.paypal.me/dvitkovsky)
[<img src="https://opencollective.com/keeweb/tiers/backer.svg?avatarHeight=42&width=880" alt="OpenCollective">](https://opencollective.com/keeweb#support)
You can also sponsor the developer directly [on GitHub](https://github.com/sponsors/antelle).
Please note: donation does not imply any type of service contract.
## Thank you
# License
Notable contributions to KeeWeb:
- Florian Reuschel ([@Loilo](https://github.com/Loilo)): [German translation](https://keeweb.oneskyapp.com/collaboration/translate/project/project/173183/language/550)
- Dennis Ploeger ([@dploeger](https://github.com/dploeger)): [auto-type improvements](https://github.com/keeweb/keeweb/pulls?q=is%3Apr+is%3Aclosed+author%3Adploeger)
- Hackmanit ([hackmanit.de](https://www.hackmanit.de)): [penetration test](https://www.hackmanit.de/en/blog-en/104-pro-bono-penetration-test-keeweb)
- Peter Bittner ([@bittner](https://github.com/bittner)): [Wikipedia article](https://en.wikipedia.org/wiki/KeeWeb)
## License
[MIT](https://github.com/keeweb/keeweb/blob/master/LICENSE)
+11
View File
@@ -0,0 +1,11 @@
# Security Policy
## Supported Versions
Only the latest version of the product is supported. This version can be accessed at https://app.keeweb.info
and downloaded from https://keeweb.info or GitHub releases ([latest release link](https://github.com/keeweb/keeweb/releases/latest)).
## Reporting a Vulnerability
We would appreciate [responsible disclosure](https://en.wikipedia.org/wiki/Responsible_disclosure).
If you would like to report a vulnerability, the preferred way to do so is [contacting the developer directly](mailto:antelle.net@gmail.com).
+28
View File
@@ -0,0 +1,28 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Not Found</title>
<style>
body {
font-family: -apple-system, 'BlinkMacSystemFont', 'Raleway', 'Helvetica Neue',
'Helvetica', 'Arial', sans-serif;
font-feature-settings: 'liga' 0;
text-align: center;
background: #f5f5f5;
font-weight: 300;
}
h1 {
font-size: 3em;
margin-top: 10vh;
}
p {
line-height: 1.5em;
}
</style>
</head>
<body>
<h1>404 Not Found</h1>
<p>Sorry, the page you're looking for was not found.</p>
</body>
</html>
+16
View File
@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>KeeWeb</title>
</head>
<body>
<script>
window.opener.postMessage(
{ storage: 'dropbox', search: location.search },
window.location.origin
);
window.close();
</script>
</body>
</html>
+16
View File
@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>KeeWeb</title>
</head>
<body>
<script>
window.opener.postMessage(
{ storage: 'gdrive', search: location.search },
window.location.origin
);
window.close();
</script>
</body>
</html>
+16
View File
@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>KeeWeb</title>
</head>
<body>
<script>
window.opener.postMessage(
{ storage: 'teams', search: location.search },
window.location.origin
);
window.close();
</script>
</body>
</html>
+16
View File
@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>KeeWeb</title>
</head>
<body>
<script>
window.opener.postMessage(
{ storage: 'onedrive', search: location.search },
window.location.origin
);
window.close();
</script>
</body>
</html>
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.0 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 685 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

+1 -1
View File
@@ -1 +1 @@
<svg version="1" xmlns="http://www.w3.org/2000/svg" width="922.667" height="922.667" viewBox="0 0 692.000000 692.000000"><path d="M266.9 57.4c-.2.2-4 .6-8.3 1-4.4.4-8.2.8-8.5 1-.3.2-2.7.7-5.3 1-5.5.7-21.6 4.8-29.8 7.5-46.3 15.4-93.3 48.9-126.5 90.1-25.7 31.8-46.8 74.8-52.9 107.4-.5 2.8-1.5 8.3-2.1 12.1-1.9 11.6-2.6 35.9-1.3 45 .3 2.7.9 7 1.2 9.5 3.3 27.4 16.9 55.4 36.1 74.5 12.1 12.1 27.3 22.7 40 27.8 3.9 1.6 7.9 3.3 9 3.7 1.1.5 4.3 1.5 7 2.4 4.4 1.3 7.1 1.9 18.5 4.1 12.1 2.4 42.4 2.4 56.5 0 1.7-.3 4.4-.7 6-1 1.7-.3 4.1-.7 5.5-1 1.4-.3 3.7-.7 5.1-1 4.5-.8 19.1-5.2 28.4-8.6 16.8-6.1 42.9-20.2 59.4-32.2l5.3-3.9 130.7 130.5C567.7 654 571.7 657.8 577.5 660c6.2 2.2 15.3 2.9 21.4 1.6 12.8-2.7 27.8-15.7 34.7-30.1 2.5-5.3 2.9-7.1 2.9-15-.1-15.8 1.1-14.3-49.6-65.1l-44-44 18.1-18.2 18.1-18.1 6.7 7.1c20.7 21.9 32.6 32.8 38.6 35.3 5.6 2.4 11.5-1.2 26.5-15.8 16.1-15.8 21.8-23.8 20-28.6-.9-2.3-4.6-7.8-7.4-10.7-.5-.6-4.1-4.8-8-9.2-7.2-8.3-64.7-65.9-91-91.1-8.2-7.9-16-14.7-17.3-15.2-6.8-2.6-12.6.8-28.4 16.3-13.1 12.9-19.8 21.8-19.8 26.3 0 5.6 13.3 21 37.4 43.4l5.8 5.4-18.1 18.1-18.1 18.1-67-67c-36.9-36.8-67-67.3-67-67.7 0-.4 3-5.1 6.7-10.4 16.1-23.5 30.3-53.8 35.8-76.4.7-2.8 4.3-22.5 5.3-28.5 1.1-6.5.8-41.1-.3-48.5-1.4-9.2-6.4-26.8-10-35.3-9.9-23.3-28.4-44.9-50.5-58.8-21.8-13.8-47.4-20.5-78.6-20.7-7.3-.1-13.3 0-13.5.2zm22 74c12.1 2.8 22.6 7.6 31.1 14.4 13.3 10.7 23.7 27.4 26.3 42.7 6 34.4-9.5 65.3-40.5 80.7-16.1 7.9-40.9 8.5-58.1 1.3-4.4-1.8-5.2-1.9-4-.3 1.1 1.4 4 9.8 4.8 13.9 5.3 25.7-.6 47.7-17.7 66-8.9 9.6-19.7 16.4-31.3 19.8-9.7 2.9-11.7 3.1-22.2 3.2-24.8 0-47.2-12.3-61-33.3-15.4-23.7-15.3-56.4.4-79.3 11.1-16.2 26.6-27.1 44.3-31.1 14.4-3.2 32.9-1.7 43.9 3.7 2 .9 3.7 1.6 3.8 1.5.2-.2-.8-3.4-2.2-7.3-3.4-9.7-3.7-11.4-4-23.3-.4-17.1 3.8-30.7 13.8-44 11.4-15.2 26.5-24.8 44.7-28.4 6.2-1.2 22.9-1.4 27.9-.2z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-64 -64 640 640"><path d="M136.736 512c-4.892-.008-10.322-2.061-15.92-4.997-11.941-6.265-20.13-14.185-13.293-27.218l166.101-316.638c-1.972-1.022-3.619-1.88-4.743-2.469-59.892-31.418-86.463-77.87-64.952-118.877 24.726-47.135 101.304-55.69 171.042-19.107 69.738 36.584 106.227 104.451 81.501 151.586-21.264 40.536-76.784 44.151-132.61 14.866-1.538-.807-4.033-2.103-6.857-3.567L150.768 502.471c-3.632 6.924-8.488 9.538-14.032 9.529zm-30.582-67.835l-3.144-1.649-.7-.366-42.546-22.32v-.001l-10.256-5.38c-1.738-.911-2.407-3.057-1.496-4.794l13.465-25.667c.906-1.728 3.036-2.399 4.768-1.509l.028.013 20.513 10.761c1.736.911 3.883.241 4.794-1.496l13.466-25.667c.911-1.737.24-3.883-1.497-4.794l-10.256-5.382-10.256-5.38c-1.737-.911-2.406-3.057-1.495-4.794l13.464-25.669c.911-1.737 3.058-2.406 4.794-1.494l10.258 5.38 26.697 14.005 16.548 8.681c.007.003.014.007.021.011l3.125 1.639-14.142 26.957-.973 1.855c0 .001-.001.003-.002.004l-20.063 38.245-2.041 3.888-11.424 21.779c-.002.004-.005.009-.008.014zm67.232-128.162l-3.145-1.651-14.938-7.837-11.794-6.187c-1.737-.911-2.408-3.057-1.497-4.794l13.466-25.667c.911-1.737 3.058-2.408 4.794-1.497l11.795 6.188 14.939 7.837c.007.003.014.007.021.01l3.125 1.64-1.651 3.145-6.731 12.834-6.733 12.833c-.003.005-.006.008-.009.013zm219.778-151.914c8.857.016 15.784-3.552 20.386-12.326 14.027-26.737-11.92-67.987-57.953-92.135-46.032-24.148-94.719-22.049-108.746 4.688-14.026 26.737 24.987 44.293 71.02 68.441 30.928 16.224 57.156 31.296 75.293 31.332z"/></svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1007 KiB

After

Width:  |  Height:  |  Size: 1013 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 947 KiB

After

Width:  |  Height:  |  Size: 960 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1020 KiB

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 315 KiB

After

Width:  |  Height:  |  Size: 322 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 405 KiB

After

Width:  |  Height:  |  Size: 408 KiB

+82 -37
View File
@@ -1,40 +1,85 @@
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>KeeWeb</title>
<meta name="application-name" content="KeeWeb">
<meta name="kw-signature" content="">
<meta name="kw-config" content="(no-config)">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="apple-mobile-web-app-title" content="KeeWeb">
<meta name="theme-color" content="#6386ec">
<meta name="msapplication-config" content="browserconfig.xml">
<meta name="msapplication-TileColor" content="#6386ec">
<link rel="apple-touch-icon" sizes="180x180" href="icons/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="icons/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="icons/favicon-16x16.png">
<link rel="mask-icon" href="icons/safari-pinned-tab.svg" color="#6386ec">
<link rel="apple-touch-startup-image" href="icons/splash-640x1136.png" media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)">
<link rel="apple-touch-startup-image" href="icons/splash-750x1294.png" media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)">
<link rel="apple-touch-startup-image" href="icons/splash-1242x2148.png" media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)">
<link rel="apple-touch-startup-image" href="icons/splash-1125x2436.png" media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)">
<link rel="apple-touch-startup-image" href="icons/splash-1536x2048.png" media="(min-device-width: 768px) and (max-device-width: 1024px) and (-webkit-min-device-pixel-ratio: 2) and (orientation: portrait)">
<link rel="apple-touch-startup-image" href="icons/splash-1668x2224.png" media="(min-device-width: 834px) and (max-device-width: 834px) and (-webkit-min-device-pixel-ratio: 2) and (orientation: portrait)">
<link rel="apple-touch-startup-image" href="icons/splash-2048x2732.png" media="(min-device-width: 1024px) and (max-device-width: 1024px) and (-webkit-min-device-pixel-ratio: 2) and (orientation: portrait)">
<link rel="manifest" href="manifest.json">
<link rel="stylesheet" href="css/main.css?__inline=true" />
<script src="js/vendor.js?__inline=true"></script>
<script src="js/app.js?__inline=true"></script>
<script src="js/runtime.js?__inline=true"></script>
</head>
<body class="th-d">
<noscript>
<h1>KeeWeb</h1>
<p>KeeWeb is a password manager written in JavaScript. Please enable JavaScript to run it.</p>
</noscript>
</body>
<head lang="en">
<meta charset="UTF-8" />
<title>KeeWeb</title>
<meta
http-equiv="Content-Security-Policy"
content="
default-src 'self';
font-src data:;
script-src 'self' 'unsafe-eval';
style-src 'self' blob:;
connect-src 'self' ws: https:;
child-src 'self' blob:;
worker-src 'self' blob:;
img-src 'self' data: blob: https://services.keeweb.info/;
object-src 'none';
form-action 'none';
"
/>
<meta name="application-name" content="KeeWeb" />
<meta name="kw-config" content="(no-config)" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
/>
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="apple-mobile-web-app-title" content="KeeWeb" />
<meta name="theme-color" content="#6386ec" />
<meta name="msapplication-config" content="browserconfig.xml" />
<meta name="msapplication-TileColor" content="#6386ec" />
<link rel="apple-touch-icon" sizes="180x180" href="icons/apple-touch-icon.png" />
<link rel="icon" type="image/png" sizes="32x32" href="icons/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="icons/favicon-16x16.png" />
<link rel="mask-icon" href="icons/safari-pinned-tab.svg" color="#6386ec" />
<link
rel="apple-touch-startup-image"
href="icons/splash-640x1136.png"
media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="icons/splash-750x1294.png"
media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="icons/splash-1242x2148.png"
media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="icons/splash-1125x2436.png"
media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="icons/splash-1536x2048.png"
media="(min-device-width: 768px) and (max-device-width: 1024px) and (-webkit-min-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="icons/splash-1668x2224.png"
media="(min-device-width: 834px) and (max-device-width: 834px) and (-webkit-min-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="icons/splash-2048x2732.png"
media="(min-device-width: 1024px) and (max-device-width: 1024px) and (-webkit-min-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link rel="manifest" href="manifest.json" />
<link rel="stylesheet" href="css/app.css?__inline=true" />
<script src="js/app.js?__inline=true"></script>
</head>
<body class="th-d">
<noscript>
<h1>KeeWeb</h1>
<p>
KeeWeb is a password manager written in JavaScript. Please enable JavaScript to run
it.
</p>
</noscript>
</body>
</html>
+71
View File
@@ -0,0 +1,71 @@
(function (global) {
var babelHelpers = global.babelHelpers = {};
babelHelpers.typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
return typeof obj;
} : function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
};
babelHelpers.defineProperty = function (obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
};
babelHelpers.slicedToArray = function () {
function sliceIterator(arr, i) {
var _arr = [];
var _n = true;
var _d = false;
var _e = undefined;
try {
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
_arr.push(_s.value);
if (i && _arr.length === i) break;
}
} catch (err) {
_d = true;
_e = err;
} finally {
try {
if (!_n && _i["return"]) _i["return"]();
} finally {
if (_d) throw _e;
}
}
return _arr;
}
return function (arr, i) {
if (Array.isArray(arr)) {
return arr;
} else if (Symbol.iterator in Object(arr)) {
return sliceIterator(arr, i);
} else {
throw new TypeError("Invalid attempt to destructure non-iterable instance");
}
};
}();
babelHelpers.toConsumableArray = function (arr) {
if (Array.isArray(arr)) {
for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
return arr2;
} else {
return Array.from(arr);
}
};
})(typeof global === "undefined" ? self : global);
-10
View File
@@ -1,10 +0,0 @@
CACHE MANIFEST
# YYYY-MM-DD:v0.0.0
# updmin:v0.0.0
CACHE:
index.html
NETWORK:
*
+19 -19
View File
@@ -1,21 +1,21 @@
{
"name": "KeeWeb",
"short_name": "KeeWeb",
"description": "Free cross-platform password manager compatible with KeePass",
"display": "standalone",
"orientation": "any",
"theme_color": "#6386ec",
"background_color": "#6386ec",
"icons": [
{
"src": "icons/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "icons/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
]
"name": "KeeWeb",
"short_name": "KeeWeb",
"description": "Free cross-platform password manager compatible with KeePass",
"start_url": "./",
"display": "standalone",
"theme_color": "#6386ec",
"background_color": "#6386ec",
"icons": [
{
"src": "icons/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "icons/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
]
}
Binary file not shown.
+9
View File
@@ -0,0 +1,9 @@
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyZAmWXMpKsh9WCyUO5TR
2/QIJsgyaViWRAgY5nHZhTR/sjhfG97OeurW7NYC4XPsnyJDepEjDsj9LNzquMES
xsLRSmxo+m1lVWn8Q59LwqOvUK+BKH4eZYF89Nwv2HZjZnr/w7xYcxJbhOuAzpbq
FD/gAvlozrsHG9uI95h1FHPd6mfolEHLK30LXPQ5FdJ/AWb29ILKYbVEdM8qsjoN
fSICw7XTbd7wB0TMcgRpjWllzKaftxCO38svhBjAz4cUvtZ05yi4dzK0VsJHfW33
uno3YBn0/bwLkqMzD1/Hv05p6CVzuDTOCBsXkEobra8OBviatoSukot6cS4Famki
9QIDAQAB
-----END PUBLIC KEY-----
+7 -7
View File
@@ -1,9 +1,9 @@
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0oZB2Kt7AzRFNqf8FuO3
C3kepHPAIQYiDPYdQxHcsiaFCwyKVx6K1cE/3vBhb8/2rj+QIIWNfAAuu1Y+2VK9
0ZBeq6HciukWzQRO/HWhfdy0c7JwDAslmyGI5olj0ZQkNLhkde1MiMxjDPpRhZtd
JaryVO5cFJaJESpv3dV6m0qXsaQCluWYOSNfSjP9C8o2zRVjSi3ZQZnZIV5pnk9K
2MtlZIPXrN9iJiM5zZ9DTSnqApI6dC9mX4R3LvGN+GTovm9C8Crl+qb106nGRR3L
cweicDnPyMtZLa/E0DBpWYxUVLDp6WeLhxoUBr+6+t3Xp9IDnPoANDQXJXD0f1vQ
xQIDAQAB
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnRq2k3TTx0ewTe6wDr6Q
VeB5diwiIWzsJD+ApfZu1KNPedcAgslAfjpNsYF1if6cYsPMJH70xJ2np6RQBl1V
PdwShOuxkD7m0BD5Hw/Aar8Hdp5cvAdOOMdBO+0DbGeUMy+z66s+oUCJmqVp19T6
PkkxbhN08rgtT7v+aFvrbqbO/vlsskbJpH2K2io+e1XmRGPnSr9q4KSqfGbTfe5g
LwDIOFd66Z4mb5Utb5wWpsy6Gjh06Yf257AccGD3A1bkTNOyeeX0tqciYBePWMk0
icP/aZ6hnErfhnUKf3tOgPLppSHiGcaSKekhChZ2xLUs3U64JwrXSmwHj+TzdO3S
0QIDAQAB
-----END PUBLIC KEY-----
+5
View File
@@ -0,0 +1,5 @@
{
"rules": {
"import/no-commonjs": "error"
}
}
+141 -95
View File
@@ -1,85 +1,105 @@
const Backbone = require('backbone');
const AppModel = require('./models/app-model');
const AppView = require('./views/app-view');
const AppSettingsModel = require('./models/app-settings-model');
const UpdateModel = require('./models/update-model');
const RuntimeDataModel = require('./models/runtime-data-model');
const FileInfoCollection = require('./collections/file-info-collection');
const KeyHandler = require('./comp/key-handler');
const IdleTracker = require('./comp/idle-tracker');
const PopupNotifier = require('./comp/popup-notifier');
const SingleInstanceChecker = require('./comp/single-instance-checker');
const AppRightsChecker = require('./comp/app-rights-checker');
const Alerts = require('./comp/alerts');
const Updater = require('./comp/updater');
const AuthReceiver = require('./comp/auth-receiver');
const ExportApi = require('./comp/export-api');
const SettingsManager = require('./comp/settings-manager');
const PluginManager = require('./plugins/plugin-manager');
const Launcher = require('./comp/launcher');
const FeatureTester = require('./comp/feature-tester');
const FocusDetector = require('./comp/focus-detector');
const Timeouts = require('./const/timeouts');
const FeatureDetector = require('./util/feature-detector');
const KdbxwebInit = require('./util/kdbxweb-init');
const Locale = require('./util/locale');
import { Events } from 'framework/events';
import { StartProfiler } from 'comp/app/start-profiler';
import { FileInfoCollection } from 'collections/file-info-collection';
import { AppRightsChecker } from 'comp/app/app-rights-checker';
import { ExportApi } from 'comp/app/export-api';
import { SingleInstanceChecker } from 'comp/app/single-instance-checker';
import { Updater } from 'comp/app/updater';
import { UsbListener } from 'comp/app/usb-listener';
import { BrowserExtensionConnector } from 'comp/extension/browser-extension-connector';
import { FeatureTester } from 'comp/browser/feature-tester';
import { FocusDetector } from 'comp/browser/focus-detector';
import { IdleTracker } from 'comp/browser/idle-tracker';
import { ThemeWatcher } from 'comp/browser/theme-watcher';
import { KeyHandler } from 'comp/browser/key-handler';
import { PopupNotifier } from 'comp/browser/popup-notifier';
import { Launcher } from 'comp/launcher';
import { SettingsManager } from 'comp/settings/settings-manager';
import { Alerts } from 'comp/ui/alerts';
import { Timeouts } from 'const/timeouts';
import { AppModel } from 'models/app-model';
import { AppSettingsModel } from 'models/app-settings-model';
import { RuntimeDataModel } from 'models/runtime-data-model';
import { UpdateModel } from 'models/update-model';
import { PluginManager } from 'plugins/plugin-manager';
import { Features } from 'util/features';
import { KdbxwebInit } from 'util/kdbxweb/kdbxweb-init';
import { Locale } from 'util/locale';
import { AppView } from 'views/app-view';
import 'hbs-helpers';
import { AutoType } from './auto-type';
import { Storage } from './storage';
const ready = Launcher && Launcher.ready || $;
StartProfiler.milestone('loading modules');
const ready = (Launcher && Launcher.ready) || $;
ready(() => {
if (AuthReceiver.receive() || FeatureDetector.isFrame) {
return;
}
loadMixins();
StartProfiler.milestone('document ready');
const appModel = new AppModel();
StartProfiler.milestone('creating app model');
Promise.resolve()
.then(loadConfigs)
.then(initModules)
.then(loadRemoteConfig)
.then(ensureCanRun)
.then(initStorage)
.then(initUsbListener)
.then(showApp)
.then(postInit)
.catch(e => {
.catch((e) => {
appModel.appLogger.error('Error starting app', e);
});
function loadMixins() {
require('./mixins/view');
require('./helpers');
}
function ensureCanRun() {
if (Features.isFrame && !appModel.settings.allowIframes) {
return Promise.reject(
'Running in iframe is not allowed (this can be changed in the app config).'
);
}
return FeatureTester.test()
.catch(e => {
.catch((e) => {
Alerts.error({
header: Locale.appSettingsError,
body: Locale.appNotSupportedError + '<br/><br/>' + e,
body: Locale.appNotSupportedError,
pre: e,
buttons: [],
esc: false, enter: false, click: false
esc: false,
enter: false,
click: false
});
throw 'Feature testing failed: ' + e;
})
.then(() => {
StartProfiler.milestone('checking features');
});
}
function loadConfigs() {
return Promise.all([
AppSettingsModel.instance.load(),
UpdateModel.instance.load(),
RuntimeDataModel.instance.load(),
FileInfoCollection.instance.load()
]);
AppSettingsModel.load(),
UpdateModel.load(),
RuntimeDataModel.load(),
FileInfoCollection.load()
]).then(() => {
StartProfiler.milestone('loading configs');
});
}
function initModules() {
KeyHandler.init();
IdleTracker.init();
PopupNotifier.init();
KdbxwebInit.init();
FocusDetector.init();
AutoType.init();
ThemeWatcher.init();
SettingsManager.init();
window.kw = ExportApi;
return PluginManager.init();
return PluginManager.init().then(() => {
StartProfiler.milestone('initializing modules');
});
}
function showSettingsLoadError() {
@@ -87,70 +107,96 @@ ready(() => {
header: Locale.appSettingsError,
body: Locale.appSettingsErrorBody,
buttons: [],
esc: false, enter: false, click: false
esc: false,
enter: false,
click: false
});
}
function loadRemoteConfig() {
return Promise.resolve()
.then(() => {
SettingsManager.setBySettings();
const configParam = getConfigParam();
if (configParam) {
return appModel
.loadConfig(configParam)
.then(() => {
SettingsManager.setBySettings();
})
.catch((e) => {
if (!appModel.settings.cacheConfigSettings) {
showSettingsLoadError();
throw e;
}
});
}
})
.then(() => {
StartProfiler.milestone('loading remote config');
});
}
function initStorage() {
for (const prv of Object.values(Storage)) {
prv.init();
}
StartProfiler.milestone('initializing storage');
}
function initUsbListener() {
UsbListener.init();
StartProfiler.milestone('starting usb');
}
function showApp() {
return Promise.resolve().then(() => {
SettingsManager.setBySettings(appModel.settings);
const configParam = getConfigParam();
if (configParam) {
return appModel.loadConfig(configParam).then(() => {
SettingsManager.setBySettings(appModel.settings);
}).catch(e => {
if (!appModel.settings.get('cacheConfigSettings')) {
showSettingsLoadError();
throw e;
}
const skipHttpsWarning =
localStorage.skipHttpsWarning || appModel.settings.skipHttpsWarning;
const protocolIsInsecure = ['https:', 'file:', 'app:'].indexOf(location.protocol) < 0;
const hostIsInsecure = location.hostname !== 'localhost';
if (protocolIsInsecure && hostIsInsecure && !skipHttpsWarning) {
return new Promise((resolve) => {
Alerts.error({
header: Locale.appSecWarn,
icon: 'user-secret',
esc: false,
enter: false,
click: false,
body: Locale.appSecWarnBody1 + '\n\n' + Locale.appSecWarnBody2,
buttons: [{ result: '', title: Locale.appSecWarnBtn, error: true }],
complete: () => {
showView();
resolve();
}
});
});
} else {
showView();
return new Promise((resolve) => requestAnimationFrame(resolve));
}
});
}
function showApp() {
return Promise.resolve()
.then(() => {
const skipHttpsWarning = localStorage.skipHttpsWarning || appModel.settings.get('skipHttpsWarning');
const protocolIsInsecure = ['https:', 'file:', 'app:'].indexOf(location.protocol) < 0;
const hostIsInsecure = location.hostname !== 'localhost';
if (protocolIsInsecure && hostIsInsecure && !skipHttpsWarning) {
return new Promise(resolve => {
Alerts.error({
header: Locale.appSecWarn, icon: 'user-secret', esc: false, enter: false, click: false,
body: Locale.appSecWarnBody1 + '<br/><br/>' + Locale.appSecWarnBody2,
buttons: [
{result: '', title: Locale.appSecWarnBtn, error: true}
],
complete: () => {
showView();
resolve();
}
});
});
} else {
showView();
}
});
}
function postInit() {
Updater.init();
SingleInstanceChecker.init();
AppRightsChecker.init();
setTimeout(() => PluginManager.runAutoUpdate(), Timeouts.AutoUpdatePluginsAfterStart);
setTimeout(() => {
Updater.init();
SingleInstanceChecker.init();
AppRightsChecker.init();
IdleTracker.init();
BrowserExtensionConnector.init(appModel);
PluginManager.runAutoUpdate();
}, Timeouts.AutoUpdatePluginsAfterStart);
}
function showView() {
appModel.prepare();
new AppView({ model: appModel }).render();
Backbone.trigger('app-ready');
logStartupTime();
}
new AppView(appModel).render();
StartProfiler.milestone('first view rendering');
function logStartupTime() {
const time = Math.round(performance.now());
appModel.appLogger.info(`Started in ${time}ms ¯\\_(ツ)_/¯`);
Events.emit('app-ready');
StartProfiler.milestone('app ready event');
StartProfiler.report();
}
function getConfigParam() {
@@ -1,13 +0,0 @@
const Launcher = require('../comp/launcher');
const AutoTypeEmitterFactory = {
create: function(callback) {
if (Launcher && Launcher.autoTypeSupported) {
const AutoTypeEmitter = require('./emitter/auto-type-emitter-' + Launcher.platform());
return new AutoTypeEmitter(callback);
}
return null;
}
};
module.exports = AutoTypeEmitterFactory;
+160
View File
@@ -0,0 +1,160 @@
import { Features } from 'util/features';
import { NativeModules } from 'comp/launcher/native-modules';
import { Logger } from 'util/logger';
import { Launcher } from 'comp/launcher';
import { Timeouts } from 'const/timeouts';
const logger = new Logger('auto-type-emitter');
const KeyMap = {
tab: 'Tab',
enter: 'Return',
space: 'Space',
up: 'UpArrow',
down: 'DownArrow',
left: 'LeftArrow',
right: 'RightArrow',
home: 'Home',
end: 'End',
pgup: 'PageUp',
pgdn: 'PageDown',
ins: 'Insert',
del: 'ForwardDelete',
bs: 'BackwardDelete',
esc: 'Escape',
win: 'Meta',
rwin: 'RightMeta',
f1: 'F1',
f2: 'F2',
f3: 'F3',
f4: 'F4',
f5: 'F5',
f6: 'F6',
f7: 'F7',
f8: 'F8',
f9: 'F9',
f10: 'F10',
f11: 'F11',
f12: 'F12',
f13: 'F13',
f14: 'F14',
f15: 'F15',
f16: 'F16',
add: 'KeypadPlus',
subtract: 'KeypadMinus',
multiply: 'KeypadMultiply',
divide: 'KeypadDivide',
n0: 'D0',
n1: 'D1',
n2: 'D2',
n3: 'D3',
n4: 'D4',
n5: 'D5',
n6: 'D6',
n7: 'D7',
n8: 'D8',
n9: 'D9'
};
const ModMap = {
'^': Features.isMac ? 'Command' : 'Ctrl',
'+': 'Shift',
'%': 'Alt',
'^^': 'Ctrl'
};
class AutoTypeEmitter {
constructor(callback) {
this.callback = callback;
this.mod = {};
}
begin() {
this.withCallback(NativeModules.kbdEnsureModifierNotPressed());
}
setMod(mod, enabled) {
const nativeMod = ModMap[mod];
if (!nativeMod) {
return this.callback(`Bad modifier: ${mod}`);
}
NativeModules.kbdKeyMoveWithModifier(!!enabled, [nativeMod]).catch((e) => {
logger.error('Error moving modifier', mod, enabled ? 'down' : 'up', e);
});
if (enabled) {
this.mod[nativeMod] = true;
} else {
delete this.mod[nativeMod];
}
}
text(str) {
if (!str) {
return this.withCallback(Promise.resolve());
}
const mods = Object.keys(this.mod);
if (mods.length) {
this.withCallback(NativeModules.kbdTextAsKeys(str, mods));
} else {
this.withCallback(NativeModules.kbdText(str));
}
}
key(key) {
const mods = Object.keys(this.mod);
if (typeof key === 'number') {
this.withCallback(NativeModules.kbdKeyPressWithCharacter(0, key, mods));
} else {
if (!KeyMap[key]) {
return this.callback('Bad key: ' + key);
}
const code = KeyMap[key];
this.withCallback(NativeModules.kbdKeyPress(code, mods));
}
}
copyPaste(text) {
setTimeout(() => {
Launcher.setClipboardText(text);
setTimeout(() => {
this.withCallback(NativeModules.kbdShortcut('V'));
}, Timeouts.AutoTypeCopyPaste);
}, Timeouts.AutoTypeCopyPaste);
}
wait(time) {
setTimeout(() => this.withCallback(Promise.resolve()), time);
}
waitComplete() {
this.withCallback(Promise.resolve());
}
setDelay() {
this.callback('Not implemented');
}
withCallback(promise) {
promise
.then(() => {
try {
this.callback();
} catch (err) {
logger.error('Callback error', err);
}
})
.catch((err) => {
const keyPressFailed = err.message === 'Key press failed';
if (keyPressFailed) {
err.keyPressFailed = true;
}
try {
this.callback(err);
} catch (err) {
logger.error('Callback error', err);
}
});
}
}
export { AutoTypeEmitter };
-85
View File
@@ -1,85 +0,0 @@
const EntryCollection = require('../collections/entry-collection');
const Ranking = require('../util/ranking');
const urlPartsRegex = /^(\w+:\/\/)?(?:(?:www|wwws|secure)\.)?([^\/]+)\/?(.*)/;
const AutoTypeFilter = function(windowInfo, appModel) {
this.title = windowInfo.title;
this.url = windowInfo.url;
this.text = '';
this.ignoreWindowInfo = false;
this.appModel = appModel;
};
AutoTypeFilter.prototype.getEntries = function() {
const filter = {
text: this.text,
autoType: true
};
this.prepareFilter();
let entries = this.appModel.getEntriesByFilter(filter)
.map(e => [e, this.getEntryRank(e)]);
if (!this.ignoreWindowInfo) {
entries = entries.filter(e => e[1]);
}
entries = entries.sort((x, y) => x[1] === y[1] ? x[0].title.localeCompare(y[0].title) : y[1] - x[1]);
entries = entries.map(p => p[0]);
return new EntryCollection(entries, {comparator: 'none'});
};
AutoTypeFilter.prototype.hasWindowInfo = function() {
return this.title || this.url;
};
AutoTypeFilter.prototype.prepareFilter = function() {
this.titleLower = this.title ? this.title.toLowerCase() : null;
this.urlLower = this.url ? this.url.toLowerCase() : null;
this.urlParts = this.url ? urlPartsRegex.exec(this.urlLower) : null;
};
AutoTypeFilter.prototype.getEntryRank = function(entry) {
let rank = 0;
if (this.titleLower && entry.title) {
rank += Ranking.getStringRank(
entry.title.toLowerCase(),
this.titleLower
);
}
if (this.urlParts && entry.url) {
const entryUrlParts = urlPartsRegex.exec(entry.url.toLowerCase());
if (entryUrlParts) {
const [, scheme, domain, path] = entryUrlParts;
const [, thisScheme, thisDomain, thisPath] = this.urlParts;
if (domain === thisDomain || thisDomain.indexOf('.' + domain) > 0) {
if (domain === thisDomain) {
rank += 20;
} else {
rank += 10;
}
if (path === thisPath) {
rank += 10;
} else if (path && thisPath) {
if (path.lastIndexOf(thisPath, 0) === 0) {
rank += 5;
} else if (thisPath.lastIndexOf(path, 0) === 0) {
rank += 3;
}
}
if (scheme === thisScheme) {
rank += 1;
}
} else {
if (entry.searchText.indexOf(this.urlLower) >= 0) {
// the url is in some field; include it
rank += 5;
} else {
// another domain; don't show this record at all, ignore title match
return 0;
}
}
}
}
return rank;
};
module.exports = AutoTypeFilter;
@@ -1,13 +0,0 @@
const Launcher = require('../comp/launcher');
const AutoTypeHelperFactory = {
create: function() {
if (Launcher && Launcher.autoTypeSupported) {
const AutoTypeHelper = require('./helper/auto-type-helper-' + Launcher.platform());
return new AutoTypeHelper();
}
return null;
}
};
module.exports = AutoTypeHelperFactory;
+16
View File
@@ -0,0 +1,16 @@
import { NativeModules } from 'comp/launcher/native-modules';
class AutoTypeHelper {
getActiveWindowInfo(callback) {
NativeModules.kbdGetActiveWindow({
getWindowTitle: true,
getBrowserUrl: true
})
.then((win) => {
callback(undefined, win);
})
.catch((err) => callback(err));
}
}
export { AutoTypeHelper };
+33 -26
View File
@@ -1,14 +1,17 @@
const Logger = require('../util/logger');
import { Logger } from 'util/logger';
const logger = new Logger('auto-type-obfuscator');
logger.setLevel(localStorage.autoTypeDebug ? Logger.Level.All : Logger.Level.Warn);
const logger = new Logger(
'auto-type-obfuscator',
undefined,
localStorage.debugAutoType ? Logger.Level.All : Logger.Level.Warn
);
const MaxFakeOps = 30;
const MaxSteps = 1000;
const MaxCopy = 2;
const FakeCharAlphabet = 'ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz123456789O0oIl';
const AutoTypeObfuscator = function(chars) {
const AutoTypeObfuscator = function (chars) {
this.chars = chars;
this.inputChars = [];
this.inputCursor = 0;
@@ -18,7 +21,7 @@ const AutoTypeObfuscator = function(chars) {
this.copyCount = 0;
};
AutoTypeObfuscator.prototype.obfuscate = function() {
AutoTypeObfuscator.prototype.obfuscate = function () {
while (!this.finished()) {
this.step();
if (this.stepCount++ > MaxSteps) {
@@ -32,12 +35,16 @@ AutoTypeObfuscator.prototype.obfuscate = function() {
return this.ops;
};
AutoTypeObfuscator.prototype.finished = function() {
return this.chars.length === this.inputChars.length &&
this.chars.every(function(ch, ix) { return this.inputChars[ix].ch === ch; }, this);
AutoTypeObfuscator.prototype.finished = function () {
return (
this.chars.length === this.inputChars.length &&
this.chars.every(function (ch, ix) {
return this.inputChars[ix].ch === ch;
}, this)
);
};
AutoTypeObfuscator.prototype.step = function() {
AutoTypeObfuscator.prototype.step = function () {
const isFake = this.stepCount < MaxFakeOps && Math.random() > this.stepCount / MaxFakeOps;
if (isFake) {
this.stepFake();
@@ -45,11 +52,11 @@ AutoTypeObfuscator.prototype.step = function() {
this.stepReal();
}
if (logger.getLevel() >= Logger.Level.Debug) {
logger.debug('value', this.inputChars.map(ic => ic.ch).join(''));
logger.debug('value', this.inputChars.map((ic) => ic.ch).join(''));
}
};
AutoTypeObfuscator.prototype.stepFake = function() {
AutoTypeObfuscator.prototype.stepFake = function () {
const pos = Math.floor(Math.random() * (this.inputChars.length + 1));
const ch = FakeCharAlphabet[Math.floor(Math.random() * FakeCharAlphabet.length)];
logger.info('step.fake', pos, ch);
@@ -78,7 +85,7 @@ AutoTypeObfuscator.prototype.stepFake = function() {
}
};
AutoTypeObfuscator.prototype.stepReal = function() {
AutoTypeObfuscator.prototype.stepReal = function () {
const possibleActions = [];
const inputRealPositions = [];
let i;
@@ -106,7 +113,7 @@ AutoTypeObfuscator.prototype.stepReal = function() {
break;
}
}
possibleActions.push({ ins: true, ch: this.chars[i], ix: i, from: from, to: to });
possibleActions.push({ ins: true, ch: this.chars[i], ix: i, from, to });
}
}
const action = possibleActions[Math.floor(Math.random() * possibleActions.length)];
@@ -127,7 +134,7 @@ AutoTypeObfuscator.prototype.stepReal = function() {
}
};
AutoTypeObfuscator.prototype.moveToPos = function(pos) {
AutoTypeObfuscator.prototype.moveToPos = function (pos) {
logger.debug('moveToPos', pos);
while (this.inputCursor > pos) {
this.moveLeft();
@@ -137,47 +144,47 @@ AutoTypeObfuscator.prototype.moveToPos = function(pos) {
}
};
AutoTypeObfuscator.prototype.moveLeft = function() {
AutoTypeObfuscator.prototype.moveLeft = function () {
logger.debug('moveLeft');
this.ops.push({ type: 'key', value: 'left' });
this.inputCursor--;
this.inputSel = 0;
};
AutoTypeObfuscator.prototype.moveRight = function() {
AutoTypeObfuscator.prototype.moveRight = function () {
logger.debug('moveRight');
this.ops.push({ type: 'key', value: 'right' });
this.inputCursor++;
this.inputSel = 0;
};
AutoTypeObfuscator.prototype.inputChar = function(ch) {
AutoTypeObfuscator.prototype.inputChar = function (ch) {
logger.debug('inputChar', ch);
this.ops.push({ type: 'text', value: ch });
this.inputChars.splice(this.inputCursor, this.inputSel, { ch: ch });
this.inputChars.splice(this.inputCursor, this.inputSel, { ch });
this.inputCursor++;
this.inputSel = 0;
};
AutoTypeObfuscator.prototype.copyPaste = function(ch) {
AutoTypeObfuscator.prototype.copyPaste = function (ch) {
logger.debug('copyPaste', ch);
this.ops.push({type: 'cmd', value: 'copyPaste', arg: ch});
this.inputChars.splice(this.inputCursor, this.inputSel, { ch: ch });
this.ops.push({ type: 'cmd', value: 'copyPaste', arg: ch });
this.inputChars.splice(this.inputCursor, this.inputSel, { ch });
this.inputCursor++;
this.inputSel = 0;
};
AutoTypeObfuscator.prototype.selectText = function(backward, count) {
AutoTypeObfuscator.prototype.selectText = function (backward, count) {
logger.debug('selectText', backward ? 'left' : 'right', count);
const ops = [];
for (let i = 0; i < count; i++) {
ops.push({ type: 'key', value: backward ? 'left' : 'right' });
}
if (ops.length === 1) {
ops[0].mod = {'+': true};
ops[0].mod = { '+': true };
this.ops.push(ops[0]);
} else {
this.ops.push({type: 'group', value: ops, mod: {'+': true}});
this.ops.push({ type: 'group', value: ops, mod: { '+': true } });
}
if (backward) {
this.inputCursor -= count;
@@ -185,7 +192,7 @@ AutoTypeObfuscator.prototype.selectText = function(backward, count) {
this.inputSel = count;
};
AutoTypeObfuscator.prototype.deleteText = function(backward) {
AutoTypeObfuscator.prototype.deleteText = function (backward) {
logger.debug('deleteText', backward ? 'left' : 'right');
this.ops.push({ type: 'key', value: backward ? 'bs' : 'del' });
if (this.inputSel) {
@@ -199,4 +206,4 @@ AutoTypeObfuscator.prototype.deleteText = function(backward) {
}
};
module.exports = AutoTypeObfuscator;
export { AutoTypeObfuscator };
+15 -15
View File
@@ -1,6 +1,6 @@
const AutoTypeRunner = require('./auto-type-runner');
import { AutoTypeRunner } from 'auto-type/auto-type-runner';
const AutoTypeParser = function(sequence) {
const AutoTypeParser = function (sequence) {
this.sequence = sequence;
this.ix = 0;
this.states = [];
@@ -8,7 +8,7 @@ const AutoTypeParser = function(sequence) {
AutoTypeParser.opRegex = /^(.*?)(?:([\s:=])[\s:=]*(.*))?$/;
AutoTypeParser.prototype.parse = function() {
AutoTypeParser.prototype.parse = function () {
const len = this.sequence.length;
this.pushState();
while (this.ix < len) {
@@ -45,14 +45,14 @@ AutoTypeParser.prototype.parse = function() {
return new AutoTypeRunner(this.state().ops);
};
AutoTypeParser.prototype.pushState = function() {
AutoTypeParser.prototype.pushState = function () {
this.states.unshift({
modifiers: null,
ops: []
});
};
AutoTypeParser.prototype.popState = function() {
AutoTypeParser.prototype.popState = function () {
if (this.states.length <= 1) {
throw 'Unexpected ")" at index ' + this.ix;
}
@@ -60,11 +60,11 @@ AutoTypeParser.prototype.popState = function() {
this.addState(state);
};
AutoTypeParser.prototype.state = function() {
AutoTypeParser.prototype.state = function () {
return this.states[0];
};
AutoTypeParser.prototype.readOp = function() {
AutoTypeParser.prototype.readOp = function () {
const toIx = this.sequence.indexOf('}', this.ix + 2);
if (toIx < 0) {
throw 'Mismatched "{" at index ' + this.ix;
@@ -79,7 +79,7 @@ AutoTypeParser.prototype.readOp = function() {
this.addOp(op, sep, arg);
};
AutoTypeParser.prototype.readModifier = function(modifier) {
AutoTypeParser.prototype.readModifier = function (modifier) {
const state = this.state();
if (!state.modifiers) {
state.modifiers = {};
@@ -91,14 +91,14 @@ AutoTypeParser.prototype.readModifier = function(modifier) {
state.modifiers[modifier] = true;
};
AutoTypeParser.prototype.resetModifiers = function() {
AutoTypeParser.prototype.resetModifiers = function () {
const state = this.state();
const modifiers = state.modifiers;
state.modifiers = null;
return modifiers;
};
AutoTypeParser.prototype.addState = function(state) {
AutoTypeParser.prototype.addState = function (state) {
this.state().ops.push({
type: 'group',
value: state.ops,
@@ -106,7 +106,7 @@ AutoTypeParser.prototype.addState = function(state) {
});
};
AutoTypeParser.prototype.addChar = function(ch) {
AutoTypeParser.prototype.addChar = function (ch) {
this.state().ops.push({
type: 'text',
value: ch,
@@ -114,14 +114,14 @@ AutoTypeParser.prototype.addChar = function(ch) {
});
};
AutoTypeParser.prototype.addOp = function(op, sep, arg) {
AutoTypeParser.prototype.addOp = function (op, sep, arg) {
this.state().ops.push({
type: 'op',
value: op,
mod: this.resetModifiers(),
sep: sep,
arg: arg
sep,
arg
});
};
module.exports = AutoTypeParser;
export { AutoTypeParser };
+202 -90
View File
@@ -1,12 +1,15 @@
const AutoTypeObfuscator = require('./auto-type-obfuscator');
const AutoTypeEmitterFactory = require('./auto-type-emitter-factory');
const Format = require('../util/format');
const Logger = require('../util/logger');
import { AutoTypeEmitter } from 'auto-type/auto-type-emitter';
import { AutoTypeObfuscator } from 'auto-type/auto-type-obfuscator';
import { StringFormat } from 'util/formatting/string-format';
import { Logger } from 'util/logger';
const emitterLogger = new Logger('auto-type-emitter');
emitterLogger.setLevel(localStorage.autoTypeDebug ? Logger.Level.All : Logger.Level.Warn);
const emitterLogger = new Logger(
'auto-type-emitter',
undefined,
localStorage.debugAutoType ? Logger.Level.All : Logger.Level.Info
);
const AutoTypeRunner = function(ops) {
const AutoTypeRunner = function (ops) {
this.ops = ops;
this.pendingResolvesCount = 0;
this.entry = null;
@@ -16,43 +19,132 @@ const AutoTypeRunner = function(ops) {
AutoTypeRunner.PendingResolve = { pending: true };
AutoTypeRunner.Keys = {
tab: 'tab', enter: 'enter', space: 'space',
up: 'up', down: 'down', left: 'left', right: 'right', home: 'home', end: 'end', pgup: 'pgup', pgdn: 'pgdn',
insert: 'ins', ins: 'ins', delete: 'del', del: 'del', backspace: 'bs', bs: 'bs', bksp: 'bs', esc: 'esc',
win: 'win', lwin: 'win', rwin: 'rwin', f1: 'f1', f2: 'f2', f3: 'f3', f4: 'f4', f5: 'f5', f6: 'f6',
f7: 'f7', f8: 'f8', f9: 'f9', f10: 'f10', f11: 'f11', f12: 'f12', f13: 'f13', f14: 'f14', f15: 'f15', f16: 'f16',
add: 'add', subtract: 'subtract', multiply: 'multiply', divide: 'divide',
numpad0: 'n0', numpad1: 'n1', numpad2: 'n2', numpad3: 'n3', numpad4: 'n4',
numpad5: 'n5', numpad6: 'n6', numpad7: 'n7', numpad8: 'n8', numpad9: 'n9'
tab: 'tab',
enter: 'enter',
space: 'space',
up: 'up',
down: 'down',
left: 'left',
right: 'right',
home: 'home',
end: 'end',
pgup: 'pgup',
pgdn: 'pgdn',
insert: 'ins',
ins: 'ins',
delete: 'del',
del: 'del',
backspace: 'bs',
bs: 'bs',
bksp: 'bs',
esc: 'esc',
win: 'win',
lwin: 'win',
rwin: 'rwin',
f1: 'f1',
f2: 'f2',
f3: 'f3',
f4: 'f4',
f5: 'f5',
f6: 'f6',
f7: 'f7',
f8: 'f8',
f9: 'f9',
f10: 'f10',
f11: 'f11',
f12: 'f12',
f13: 'f13',
f14: 'f14',
f15: 'f15',
f16: 'f16',
add: 'add',
subtract: 'subtract',
multiply: 'multiply',
divide: 'divide',
numpad0: 'n0',
numpad1: 'n1',
numpad2: 'n2',
numpad3: 'n3',
numpad4: 'n4',
numpad5: 'n5',
numpad6: 'n6',
numpad7: 'n7',
numpad8: 'n8',
numpad9: 'n9'
};
AutoTypeRunner.Substitutions = {
title: function(runner, op) { return runner.getEntryFieldKeys('Title', op); },
username: function(runner, op) { return runner.getEntryFieldKeys('UserName', op); },
url: function(runner, op) { return runner.getEntryFieldKeys('URL', op); },
password: function(runner, op) { return runner.getEntryFieldKeys('Password', op); },
notes: function(runner, op) { return runner.getEntryFieldKeys('Notes', op); },
group: function(runner) { return runner.getEntryGroupName(); },
totp: function(runner, op) { return runner.getOtp(op); },
s: function(runner, op) { return runner.getEntryFieldKeys(op.arg, op); },
'dt_simple': function(runner) { return runner.dt('simple'); },
'dt_year': function(runner) { return runner.dt('Y'); },
'dt_month': function(runner) { return runner.dt('M'); },
'dt_day': function(runner) { return runner.dt('D'); },
'dt_hour': function(runner) { return runner.dt('h'); },
'dt_minute': function(runner) { return runner.dt('m'); },
'dt_second': function(runner) { return runner.dt('s'); },
'dt_utc_simple': function(runner) { return runner.udt('simple'); },
'dt_utc_year': function(runner) { return runner.udt('Y'); },
'dt_utc_month': function(runner) { return runner.udt('M'); },
'dt_utc_day': function(runner) { return runner.udt('D'); },
'dt_utc_hour': function(runner) { return runner.udt('h'); },
'dt_utc_minute': function(runner) { return runner.udt('m'); },
'dt_utc_second': function(runner) { return runner.udt('s'); }
title(runner, op) {
return runner.getEntryFieldKeys('Title', op);
},
username(runner, op) {
return runner.getEntryFieldKeys('UserName', op);
},
url(runner, op) {
return runner.getEntryFieldKeys('URL', op);
},
password(runner, op) {
return runner.getEntryFieldKeys('Password', op);
},
notes(runner, op) {
return runner.getEntryFieldKeys('Notes', op);
},
group(runner) {
return runner.getEntryGroupName();
},
totp(runner, op) {
return runner.getOtp(op);
},
s(runner, op) {
return runner.getEntryFieldKeys(op.arg, op);
},
'dt_simple'(runner) {
return runner.dt('simple');
},
'dt_year'(runner) {
return runner.dt('Y');
},
'dt_month'(runner) {
return runner.dt('M');
},
'dt_day'(runner) {
return runner.dt('D');
},
'dt_hour'(runner) {
return runner.dt('h');
},
'dt_minute'(runner) {
return runner.dt('m');
},
'dt_second'(runner) {
return runner.dt('s');
},
'dt_utc_simple'(runner) {
return runner.udt('simple');
},
'dt_utc_year'(runner) {
return runner.udt('Y');
},
'dt_utc_month'(runner) {
return runner.udt('M');
},
'dt_utc_day'(runner) {
return runner.udt('D');
},
'dt_utc_hour'(runner) {
return runner.udt('h');
},
'dt_utc_minute'(runner) {
return runner.udt('m');
},
'dt_utc_second'(runner) {
return runner.udt('s');
}
};
AutoTypeRunner.prototype.resolve = function(entry, callback) {
AutoTypeRunner.prototype.resolve = function (entry, context, callback) {
this.entry = entry;
this.context = context;
try {
this.resolveOps(this.ops);
if (!this.pendingResolvesCount) {
@@ -65,7 +157,7 @@ AutoTypeRunner.prototype.resolve = function(entry, callback) {
}
};
AutoTypeRunner.prototype.resolveOps = function(ops) {
AutoTypeRunner.prototype.resolveOps = function (ops) {
for (let i = 0, len = ops.length; i < len; i++) {
const op = ops[i];
if (op.type === 'group') {
@@ -76,7 +168,7 @@ AutoTypeRunner.prototype.resolveOps = function(ops) {
}
};
AutoTypeRunner.prototype.resolveOp = function(op) {
AutoTypeRunner.prototype.resolveOp = function (op) {
if (op.value.length === 1 && !op.sep) {
// {x}
op.type = 'text';
@@ -103,7 +195,7 @@ AutoTypeRunner.prototype.resolveOp = function(op) {
op.value = [];
const count = +op.arg;
for (let i = 0; i < count; i++) {
op.value.push({type: 'key', value: key});
op.value.push({ type: 'key', value: key });
}
} else {
// {TAB}
@@ -112,6 +204,11 @@ AutoTypeRunner.prototype.resolveOp = function(op) {
}
return;
}
if (this.context?.resolved?.[lowerValue]) {
op.type = 'text';
op.value = this.context.resolved[lowerValue];
return;
}
const substitution = AutoTypeRunner.Substitutions[lowerValue];
if (substitution) {
// {title}
@@ -127,7 +224,7 @@ AutoTypeRunner.prototype.resolveOp = function(op) {
}
};
AutoTypeRunner.prototype.tryParseCommand = function(op) {
AutoTypeRunner.prototype.tryParseCommand = function (op) {
switch (op.value.toLowerCase()) {
case 'clearfield':
// {CLEARFIELD}
@@ -142,7 +239,7 @@ AutoTypeRunner.prototype.tryParseCommand = function(op) {
// {VKEY 10} {VKEY 0x1F}
op.type = 'key';
op.value = parseInt(op.arg);
if (isNaN(op.value) || op.value <= 0) {
if (isNaN(op.value) || op.value < 0) {
throw 'Bad vkey: ' + op.arg;
}
return true;
@@ -166,7 +263,7 @@ AutoTypeRunner.prototype.tryParseCommand = function(op) {
}
};
AutoTypeRunner.prototype.getEntryFieldKeys = function(field, op) {
AutoTypeRunner.prototype.getEntryFieldKeys = function (field, op) {
if (!field || !this.entry) {
return '';
}
@@ -177,11 +274,11 @@ AutoTypeRunner.prototype.getEntryFieldKeys = function(field, op) {
if (value.isProtected) {
op.type = 'group';
const ops = [];
value.forEachChar(ch => {
value.forEachChar((ch) => {
if (ch === 10 || ch === 13) {
ops.push({type: 'key', value: 'enter'});
ops.push({ type: 'key', value: 'enter' });
} else {
ops.push({type: 'text', value: String.fromCharCode(ch)});
ops.push({ type: 'text', value: String.fromCharCode(ch) });
}
});
return ops;
@@ -192,65 +289,79 @@ AutoTypeRunner.prototype.getEntryFieldKeys = function(field, op) {
}
op.type = 'group';
const partsOps = [];
parts.forEach(part => {
parts.forEach((part) => {
if (partsOps.length) {
partsOps.push({type: 'key', value: 'enter'});
partsOps.push({ type: 'key', value: 'enter' });
}
if (part) {
partsOps.push({type: 'text', value: part});
partsOps.push({ type: 'text', value: part });
}
});
return partsOps;
}
};
AutoTypeRunner.prototype.getEntryGroupName = function() {
return this.entry && this.entry.group.get('title');
AutoTypeRunner.prototype.getEntryGroupName = function () {
return this.entry && this.entry.group.title;
};
AutoTypeRunner.prototype.dt = function(part) {
AutoTypeRunner.prototype.dt = function (part) {
switch (part) {
case 'simple':
return this.dt('Y') + this.dt('M') + this.dt('D') + this.dt('h') + this.dt('m') + this.dt('s');
return (
this.dt('Y') +
this.dt('M') +
this.dt('D') +
this.dt('h') +
this.dt('m') +
this.dt('s')
);
case 'Y':
return this.now.getFullYear().toString();
case 'M':
return Format.pad(this.now.getMonth() + 1, 2);
return StringFormat.pad(this.now.getMonth() + 1, 2);
case 'D':
return Format.pad(this.now.getDate(), 2);
return StringFormat.pad(this.now.getDate(), 2);
case 'h':
return Format.pad(this.now.getHours(), 2);
return StringFormat.pad(this.now.getHours(), 2);
case 'm':
return Format.pad(this.now.getMinutes(), 2);
return StringFormat.pad(this.now.getMinutes(), 2);
case 's':
return Format.pad(this.now.getSeconds(), 2);
return StringFormat.pad(this.now.getSeconds(), 2);
default:
throw 'Bad part: ' + part;
}
};
AutoTypeRunner.prototype.udt = function(part) {
AutoTypeRunner.prototype.udt = function (part) {
switch (part) {
case 'simple':
return this.udt('Y') + this.udt('M') + this.udt('D') + this.udt('h') + this.udt('m') + this.udt('s');
return (
this.udt('Y') +
this.udt('M') +
this.udt('D') +
this.udt('h') +
this.udt('m') +
this.udt('s')
);
case 'Y':
return this.now.getUTCFullYear().toString();
case 'M':
return Format.pad(this.now.getUTCMonth() + 1, 2);
return StringFormat.pad(this.now.getUTCMonth() + 1, 2);
case 'D':
return Format.pad(this.now.getUTCDate(), 2);
return StringFormat.pad(this.now.getUTCDate(), 2);
case 'h':
return Format.pad(this.now.getUTCHours(), 2);
return StringFormat.pad(this.now.getUTCHours(), 2);
case 'm':
return Format.pad(this.now.getUTCMinutes(), 2);
return StringFormat.pad(this.now.getUTCMinutes(), 2);
case 's':
return Format.pad(this.now.getUTCSeconds(), 2);
return StringFormat.pad(this.now.getUTCSeconds(), 2);
default:
throw 'Bad part: ' + part;
}
};
AutoTypeRunner.prototype.getOtp = function(op) {
AutoTypeRunner.prototype.getOtp = function (op) {
if (!this.entry) {
return '';
}
@@ -258,13 +369,13 @@ AutoTypeRunner.prototype.getOtp = function(op) {
if (!this.entry.otpGenerator) {
return '';
}
this.entry.otpGenerator.next(otp => {
this.pendingResolved(op, otp, otp ? undefined : 'OTP error');
this.entry.otpGenerator.next((err, otp) => {
this.pendingResolved(op, otp, err);
});
return AutoTypeRunner.PendingResolve;
};
AutoTypeRunner.prototype.pendingResolved = function(op, value, error) {
AutoTypeRunner.prototype.pendingResolved = function (op, value, error) {
const wasPending = op.value === AutoTypeRunner.PendingResolve;
if (value) {
op.value = value;
@@ -279,11 +390,11 @@ AutoTypeRunner.prototype.pendingResolved = function(op, value, error) {
}
};
AutoTypeRunner.prototype.obfuscate = function() {
AutoTypeRunner.prototype.obfuscate = function () {
this.obfuscateOps(this.ops);
};
AutoTypeRunner.prototype.obfuscateOps = function(ops) {
AutoTypeRunner.prototype.obfuscateOps = function (ops) {
for (let i = 0, len = ops.length; i < len; i++) {
const op = ops[i];
if (op.mod) {
@@ -292,7 +403,7 @@ AutoTypeRunner.prototype.obfuscateOps = function(ops) {
if (op.type === 'text') {
this.obfuscateOp(op);
} else if (op.type === 'group') {
const onlyText = op.value.every(grOp => grOp.type === 'text' && !grOp.mod);
const onlyText = op.value.every((grOp) => grOp.type === 'text' && !grOp.mod);
if (onlyText) {
this.obfuscateOp(op);
} else {
@@ -302,7 +413,7 @@ AutoTypeRunner.prototype.obfuscateOps = function(ops) {
}
};
AutoTypeRunner.prototype.obfuscateOp = function(op) {
AutoTypeRunner.prototype.obfuscateOp = function (op) {
let letters = [];
if (op.type === 'text') {
if (!op.value || op.value.length <= 1) {
@@ -310,7 +421,7 @@ AutoTypeRunner.prototype.obfuscateOp = function(op) {
}
letters = op.value.split('');
} else {
op.value.forEach(grOp => letters.push.apply(letters, grOp.value.split('')));
op.value.forEach((grOp) => letters.push(...grOp.value.split('')));
}
if (letters.length <= 1) {
return;
@@ -320,10 +431,10 @@ AutoTypeRunner.prototype.obfuscateOp = function(op) {
op.type = 'group';
};
AutoTypeRunner.prototype.run = function(callback) {
this.emitter = AutoTypeEmitterFactory.create(this.emitNext.bind(this));
AutoTypeRunner.prototype.run = function (callback, windowId) {
this.emitter = new AutoTypeEmitter(this.emitNext.bind(this), windowId);
this.emitterState = {
callback: callback,
callback,
stack: [],
ops: this.ops,
opIx: 0,
@@ -331,10 +442,10 @@ AutoTypeRunner.prototype.run = function(callback) {
activeMod: {},
finished: null
};
this.emitNext();
this.emitter.begin();
};
AutoTypeRunner.prototype.emitNext = function(err) {
AutoTypeRunner.prototype.emitNext = function (err) {
if (err) {
this.emitterState.finished = true;
this.emitterState.callback(err);
@@ -348,7 +459,7 @@ AutoTypeRunner.prototype.emitNext = function(err) {
if (this.emitterState.opIx >= this.emitterState.ops.length) {
const state = this.emitterState.stack.pop();
if (state) {
_.extend(this.emitterState, { ops: state.ops, opIx: state.opIx, mod: state.mod });
Object.assign(this.emitterState, { ops: state.ops, opIx: state.opIx, mod: state.mod });
this.emitNext();
} else {
this.resetEmitterMod({});
@@ -366,12 +477,12 @@ AutoTypeRunner.prototype.emitNext = function(err) {
this.emitterState.stack.push({
ops: this.emitterState.ops,
opIx: this.emitterState.opIx + 1,
mod: _.clone(this.emitterState.mod)
mod: { ...this.emitterState.mod }
});
_.extend(this.emitterState, {
Object.assign(this.emitterState, {
ops: op.value,
opIx: 0,
mod: _.clone(this.emitterState.activeMod)
mod: { ...this.emitterState.activeMod }
});
this.emitNext();
return;
@@ -393,7 +504,7 @@ AutoTypeRunner.prototype.emitNext = function(err) {
emitterLogger.debug('key', op.value);
this.emitter.key(op.value);
break;
case 'cmd':
case 'cmd': {
const method = this.emitter[op.value];
if (!method) {
throw 'Bad cmd: ' + op.value;
@@ -401,13 +512,14 @@ AutoTypeRunner.prototype.emitNext = function(err) {
emitterLogger.debug(op.value, op.arg);
method.call(this.emitter, op.arg);
break;
}
default:
throw 'Bad op: ' + op.type;
}
};
AutoTypeRunner.prototype.setEmitterMod = function(addedMod) {
Object.keys(addedMod).forEach(function(mod) {
AutoTypeRunner.prototype.setEmitterMod = function (addedMod) {
Object.keys(addedMod).forEach(function (mod) {
if (addedMod[mod] && !this.emitterState.activeMod[mod]) {
emitterLogger.debug('mod', mod, true);
this.emitter.setMod(mod, true);
@@ -416,8 +528,8 @@ AutoTypeRunner.prototype.setEmitterMod = function(addedMod) {
}, this);
};
AutoTypeRunner.prototype.resetEmitterMod = function(targetState) {
Object.keys(this.emitterState.activeMod).forEach(function(mod) {
AutoTypeRunner.prototype.resetEmitterMod = function (targetState) {
Object.keys(this.emitterState.activeMod).forEach(function (mod) {
if (this.emitterState.activeMod[mod] && !targetState[mod]) {
emitterLogger.debug('mod', mod, false);
this.emitter.setMod(mod, false);
@@ -426,4 +538,4 @@ AutoTypeRunner.prototype.resetEmitterMod = function(targetState) {
}, this);
};
module.exports = AutoTypeRunner;
export { AutoTypeRunner };
@@ -1,91 +0,0 @@
const Launcher = require('../../comp/launcher');
const AutoTypeNativeHelper = require('../helper/auto-type-native-helper');
// http://eastmanreference.com/complete-list-of-applescript-key-codes/
const KeyMap = {
tab: 48, enter: 36, space: 49,
up: 126, down: 125, left: 123, right: 124, home: 115, end: 119, pgup: 116, pgdn: 121,
ins: 114, del: 117, bs: 51, esc: 53,
win: 55, rwin: 55,
f1: 122, f2: 120, f3: 99, f4: 118, f5: 96, f6: 97, f7: 98, f8: 100, f9: 101,
f10: 109, f11: 103, f12: 111, f13: 105, f14: 107, f15: 113, f16: 106,
add: 69, subtract: 78, multiply: 67, divide: 75,
n0: 82, n1: 83, n2: 84, n3: 85, n4: 86,
n5: 87, n6: 88, n7: 89, n8: 91, n9: 92
};
const ModMap = {
'^': '@',
'+': '+',
'%': '%',
'^^': '^'
};
const AutoTypeEmitter = function(callback) {
this.callback = callback;
this.mod = {};
this.pendingScript = [];
};
AutoTypeEmitter.prototype.setMod = function(mod, enabled) {
if (enabled) {
this.mod[ModMap[mod]] = true;
} else {
delete this.mod[ModMap[mod]];
}
};
AutoTypeEmitter.prototype.text = function(text) {
this.pendingScript.push('text ' + this.modString() + ' ' + text);
this.callback();
};
AutoTypeEmitter.prototype.key = function(key) {
if (typeof key !== 'number') {
if (!KeyMap[key]) {
return this.callback('Bad key: ' + key);
}
key = KeyMap[key];
}
this.pendingScript.push('key ' + this.modString() + key);
this.callback();
};
AutoTypeEmitter.prototype.copyPaste = function(text) {
this.pendingScript.push('copypaste ' + text);
this.callback();
};
AutoTypeEmitter.prototype.wait = function(time) {
this.pendingScript.push('wait ' + time);
this.callback();
};
AutoTypeEmitter.prototype.waitComplete = function() {
if (this.pendingScript.length) {
const script = this.pendingScript.join('\n');
this.pendingScript.length = 0;
this.runScript(script);
} else {
this.callback();
}
};
AutoTypeEmitter.prototype.setDelay = function(delay) {
this.delay = delay || 0;
this.callback('Not implemented');
};
AutoTypeEmitter.prototype.modString = function() {
return Object.keys(this.mod).join('');
};
AutoTypeEmitter.prototype.runScript = function(script) {
Launcher.spawn({
cmd: AutoTypeNativeHelper.getHelperPath(),
data: script,
complete: this.callback
});
};
module.exports = AutoTypeEmitter;
@@ -1,109 +0,0 @@
const Launcher = require('../../comp/launcher');
const Locale = require('../../util/locale');
// https://cgit.freedesktop.org/xorg/proto/x11proto/plain/keysymdef.h
const KeyMap = {
tab: 'Tab', enter: 'KP_Enter', space: 'KP_Space',
up: 'Up', down: 'Down', left: 'Left', right: 'Right', home: 'Home', end: 'End', pgup: 'Page_Up', pgdn: 'Page_Down',
ins: 'Insert', del: 'Delete', bs: 'BackSpace', esc: 'Escape',
win: 'Meta_L', rwin: 'Meta_R',
f1: 'F1', f2: 'F2', f3: 'F3', f4: 'F4', f5: 'F5', f6: 'F6', f7: 'F7', f8: 'F8', f9: 'F9',
f10: 'F10', f11: 'F11', f12: 'F12', f13: 'F13', f14: 'F14', f15: 'F15', f16: 'F16',
add: 'KP_Add', subtract: 'KP_Subtract', multiply: 'KP_Multiply', divide: 'KP_Divide',
n0: 'KP_0', n1: 'KP_1', n2: 'KP_2', n3: 'KP_3', n4: 'KP_4',
n5: 'KP_5', n6: 'KP_6', n7: 'KP_7', n8: 'KP_8', n9: 'KP_9'
};
const ModMap = {
'^': 'ctrl',
'+': 'shift',
'%': 'alt',
'^^': 'ctrl'
};
const AutoTypeEmitter = function(callback) {
this.callback = callback;
this.mod = {};
this.pendingScript = [];
};
AutoTypeEmitter.prototype.setMod = function(mod, enabled) {
if (enabled) {
this.mod[ModMap[mod]] = true;
} else {
delete this.mod[ModMap[mod]];
}
};
AutoTypeEmitter.prototype.text = function(text) {
this.pendingScript.push('keyup ctrl alt shift t');
Object.keys(this.mod).forEach(mod => {
this.pendingScript.push('keydown ' + ModMap[mod]);
});
text.split('').map(char => {
this.pendingScript.push('key U' + char.charCodeAt(0).toString(16));
});
Object.keys(this.mod).forEach(mod => {
this.pendingScript.push('keyup ' + ModMap[mod]);
});
this.waitComplete();
};
AutoTypeEmitter.prototype.key = function(key) {
if (typeof key !== 'number') {
if (!KeyMap[key]) {
return this.callback('Bad key: ' + key);
}
key = KeyMap[key].toString(16);
}
this.pendingScript.push('key --clearmodifiers ' + this.modString() + key);
this.callback();
};
AutoTypeEmitter.prototype.copyPaste = function(text) {
this.pendingScript.push('sleep 0.5');
Launcher.setClipboardText(text);
this.pendingScript.push('key --clearmodifiers shift+Insert');
this.pendingScript.push('sleep 0.5');
this.waitComplete();
};
AutoTypeEmitter.prototype.wait = function(time) {
this.pendingScript.push('sleep ' + (time / 1000));
this.callback();
};
AutoTypeEmitter.prototype.waitComplete = function(callback) {
if (this.pendingScript.length) {
const script = this.pendingScript.join(' ');
this.pendingScript.length = 0;
this.runScript(script, callback);
} else {
this.callback();
}
};
AutoTypeEmitter.prototype.modString = function() {
let mod = '';
Object.keys(this.mod).forEach(key => {
mod += key + '+';
});
return mod;
};
AutoTypeEmitter.prototype.runScript = function(script, callback) {
Launcher.spawn({
cmd: 'xdotool',
args: ['-'],
data: script,
complete: (err, stdout, code) => {
if (err && err.code === 'ENOENT') {
err = Locale.autoTypeErrorNotInstalled.replace('{}', 'xdotool');
}
const cb = callback || this.callback;
cb(err, stdout, code);
}
});
};
module.exports = AutoTypeEmitter;
@@ -1,93 +0,0 @@
const Launcher = require('../../comp/launcher');
const AutoTypeNativeHelper = require('../helper/auto-type-native-helper');
// https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx
const KeyMap = {
tab: 0x09, enter: 0x0D, space: 0x20,
up: 0x26, down: 0x28, left: 0x25, right: 0x27, home: 0x24, end: 0x23, pgup: 0x21, pgdn: 0x22,
ins: 0x2D, del: 0x2E, bs: 0x08, esc: 0x1B,
win: 0x5B, rwin: 0x5C,
f1: 0x70, f2: 0x71, f3: 0x72, f4: 0x73, f5: 0x74, f6: 0x75, f7: 0x76, f8: 0x77, f9: 0x78,
f10: 0x79, f11: 0x7A, f12: 0x7B, f13: 0x7C, f14: 0x7D, f15: 0x7E, f16: 0x7F,
add: 0x6B, subtract: 0x6D, multiply: 0x6A, divide: 0x6F,
n0: 0x30, n1: 0x31, n2: 0x32, n3: 0x33, n4: 0x34,
n5: 0x35, n6: 0x36, n7: 0x37, n8: 0x38, n9: 0x39
};
const ModMap = {
'^': '^',
'+': '+',
'%': '%',
'^^': '^'
};
const AutoTypeEmitter = function(callback) {
this.callback = callback;
this.mod = {};
this.pendingScript = [];
};
AutoTypeEmitter.prototype.setMod = function(mod, enabled) {
if (enabled) {
this.mod[ModMap[mod]] = true;
} else {
delete this.mod[ModMap[mod]];
}
};
AutoTypeEmitter.prototype.text = function(text) {
if (text) {
this.pendingScript.push('text ' + this.modStr() + ' ' + text);
}
this.callback();
};
AutoTypeEmitter.prototype.key = function(key) {
if (typeof key !== 'number') {
if (!KeyMap[key]) {
return this.callback('Bad key: ' + key);
}
key = KeyMap[key];
}
this.pendingScript.push('key ' + this.modStr() + key);
this.callback();
};
AutoTypeEmitter.prototype.copyPaste = function(text) {
this.pendingScript.push('copypaste ' + text);
this.callback();
};
AutoTypeEmitter.prototype.wait = function(time) {
this.pendingScript.push('wait ' + time);
this.callback();
};
AutoTypeEmitter.prototype.waitComplete = function() {
if (this.pendingScript.length) {
const script = this.pendingScript.join('\n');
this.pendingScript.length = 0;
this.runScript(script);
} else {
this.callback();
}
};
AutoTypeEmitter.prototype.setDelay = function(delay) {
this.delay = delay || 0;
this.callback('Not implemented');
};
AutoTypeEmitter.prototype.modStr = function() {
return Object.keys(this.mod).join('');
};
AutoTypeEmitter.prototype.runScript = function(script) {
Launcher.spawn({
cmd: AutoTypeNativeHelper.getHelperPath(),
data: script,
complete: this.callback
});
};
module.exports = AutoTypeEmitter;
@@ -1,59 +0,0 @@
const Launcher = require('../../comp/launcher');
const ForeMostAppScript = 'tell application "System Events" to set frontApp to name of first process whose frontmost is true';
const ChromeScript = 'tell application "{}" to set appUrl to URL of active tab of front window\n' +
'tell application "{}" to set appTitle to title of active tab of front window\n' +
'return appUrl & "\n" & appTitle';
const SafariScript = 'tell application "{}" to set appUrl to URL of front document\n' +
'tell application "{}" to set appTitle to name of front document\n' +
'return appUrl & "\n" & appTitle';
const OtherAppsScript = 'tell application "System Events"\n' +
' tell process "{}"\n' +
' tell (1st window whose value of attribute "AXMain" is true)\n' +
' set windowTitle to value of attribute "AXTitle"\n' +
' end tell\n' +
' end tell\n' +
'end tell';
const AutoTypeHelper = function() {
};
AutoTypeHelper.prototype.getActiveWindowTitle = function(callback) {
AutoTypeHelper.exec(ForeMostAppScript, (err, out) => {
if (err) { return callback(err); }
const appName = out.trim();
// getting urls and titles from Chrome or Safari:
// - will suit in 90% cases
// - does not require assistive access
// - allows to get url
if (['Google Chrome', 'Chromium', 'Google Chrome Canary'].indexOf(appName) >= 0) {
AutoTypeHelper.exec(ChromeScript.replace(/\{}/g, appName), (err, out) => {
if (err) { return callback(err); }
const parts = out.split('\n');
return callback(null, (parts[1] || '').trim(), parts[0].trim());
});
} else if (['Safari', 'Webkit'].indexOf(appName) >= 0) {
AutoTypeHelper.exec(SafariScript.replace(/\{}/g, appName), (err, out) => {
if (err) { return callback(err); }
const parts = out.split('\n');
return callback(null, (parts[1] || '').trim(), parts[0].trim());
});
} else {
// special cases are not available. this method may ask the user about assistive access
AutoTypeHelper.exec(OtherAppsScript.replace(/\{}/g, appName), (err, out) => {
if (err) { return callback(err); }
return callback(null, out.trim());
});
}
});
};
AutoTypeHelper.exec = function(script, callback) {
Launcher.spawn({
cmd: 'osascript',
args: ['-e', script],
complete: callback
});
};
module.exports = AutoTypeHelper;
@@ -1,16 +0,0 @@
const Launcher = require('../../comp/launcher');
const AutoTypeHelper = function() {
};
AutoTypeHelper.prototype.getActiveWindowTitle = function(callback) {
Launcher.spawn({
cmd: 'xdotool',
args: ['getactivewindow', 'getwindowname'],
complete: function(err, res) {
return callback(err, res ? res.trim() : undefined);
}
});
};
module.exports = AutoTypeHelper;
@@ -1,20 +0,0 @@
const Launcher = require('../../comp/launcher');
const AutoTypeNativeHelper = require('./auto-type-native-helper');
const AutoTypeHelper = function() {
};
AutoTypeHelper.prototype.getActiveWindowTitle = function(callback) {
Launcher.spawn({
cmd: AutoTypeNativeHelper.getHelperPath(),
args: ['--window-info'],
complete: function(err, out) {
if (err) { return callback(err); }
const parts = out.split('\n');
return callback(null, (parts[0] || '').trim(),
parts[1] ? parts[1].trim() : undefined);
}
});
};
module.exports = AutoTypeHelper;
@@ -1,21 +0,0 @@
const Launcher = require('../../comp/launcher');
const Logger = require('../../util/logger');
const logger = new Logger('auto-type');
const AutoTypeNativeHelper = {
getHelperPath() {
if (this._helperPath) {
return this._helperPath;
}
const ext = process.platform === 'win32' ? '.exe' : '';
const helperRelPath = `helper/${process.platform}/KeeWebHelper${ext}`;
const helperPath = Launcher.getAppPath(helperRelPath);
Launcher.ensureRunnable(helperPath);
logger.debug('Using auto-type helper', helperPath);
this._helperPath = helperPath;
return helperPath;
}
};
module.exports = AutoTypeNativeHelper;
+154 -96
View File
@@ -1,44 +1,47 @@
const Backbone = require('backbone');
const AutoTypeParser = require('./auto-type-parser');
const AutoTypeFilter = require('./auto-type-filter');
const AutoTypeHelperFactory = require('./auto-type-helper-factory');
const Launcher = require('../comp/launcher');
const Alerts = require('../comp/alerts');
const AutoTypeSelectView = require('../views/auto-type/auto-type-select-view');
const Logger = require('../util/logger');
const Locale = require('../util/locale');
const Timeouts = require('../const/timeouts');
const AppSettingsModel = require('../models/app-settings-model');
const AutoTypeSequenceType = require('../const/autotype-sequencetype');
import { Events } from 'framework/events';
import { AutoTypeHelper } from 'auto-type/auto-type-helper';
import { AutoTypeParser } from 'auto-type/auto-type-parser';
import { SelectEntryFilter } from 'comp/app/select-entry-filter';
import { Launcher } from 'comp/launcher';
import { Features } from 'util/features';
import { Alerts } from 'comp/ui/alerts';
import { Timeouts } from 'const/timeouts';
import { AppSettingsModel } from 'models/app-settings-model';
import { AppModel } from 'models/app-model';
import { Locale } from 'util/locale';
import { Logger } from 'util/logger';
import { Links } from 'const/links';
import { SelectEntryView } from 'views/select/select-entry-view';
const logger = new Logger('auto-type');
const clearTextAutoTypeLog = localStorage.autoTypeDebug;
const clearTextAutoTypeLog = !!localStorage.debugAutoType;
const AutoType = {
helper: AutoTypeHelperFactory.create(),
enabled: !!(Launcher && Launcher.autoTypeSupported),
supportsEventsWithWindowId: !!(Launcher && Launcher.platform() === 'linux'),
selectEntryView: false,
pendingEvent: null,
running: false,
init(appModel) {
init() {
if (!this.enabled) {
return;
}
this.appModel = appModel;
Backbone.on('auto-type', this.handleEvent, this);
Backbone.on('main-window-blur main-window-will-close', this.resetPendingEvent, this);
Events.on('auto-type', (e) => this.handleEvent(e));
},
handleEvent(e) {
const entry = e && e.entry || null;
const entry = (e && e.entry) || null;
const sequence = (e && e.sequence) || null;
const context = (e && e.context) || null;
logger.debug('Auto type event', entry);
if (this.running) {
logger.debug('Already running, skipping event');
return;
}
if (entry) {
this.hideWindow(() => { this.runAndHandleResult({ entry }); });
this.hideWindow(() => {
this.runAndHandleResult({ entry, sequence, context });
});
} else {
if (this.selectEntryView) {
return;
@@ -54,38 +57,39 @@ const AutoType = {
}
},
runAndHandleResult(result) {
this.run(result, err => {
runAndHandleResult(result, windowId) {
this.run(result, windowId, (err) => {
if (err) {
let body = Locale.autoTypeErrorGeneric.replace('{}', err.message || err.toString());
let link;
if (err.keyPressFailed && Features.isMac) {
body = Locale.autoTypeErrorAccessibilityMacOS;
link = Links.AutoTypeMacOS;
}
Alerts.error({
header: Locale.autoTypeError,
body: Locale.autoTypeErrorGeneric.replace('{}', err.toString())
body,
link
});
}
});
if (AppSettingsModel.instance.get('lockOnAutoType')) {
Backbone.trigger('lock-workspace');
if (AppSettingsModel.lockOnAutoType) {
Events.emit('lock-workspace');
}
},
run(result, callback) {
run(result, windowId, callback) {
this.running = true;
let sequence;
if (result.sequenceType === AutoTypeSequenceType.PASSWORD) {
sequence = '{PASSWORD}';
} else if (result.sequenceType === AutoTypeSequenceType.USERNAME) {
sequence = '{USERNAME}';
} else {
sequence = result.entry.getEffectiveAutoTypeSeq();
}
const sequence = result.sequence || result.entry.getEffectiveAutoTypeSeq();
const context = result.context;
logger.debug('Start', sequence);
const ts = logger.ts();
try {
const parser = new AutoTypeParser(sequence);
const runner = parser.parse();
logger.debug('Parsed', this.printOps(runner.ops));
runner.resolve(result.entry, err => {
runner.resolve(result.entry, context, (err) => {
if (err) {
this.running = false;
logger.error('Resolve error', err);
@@ -102,7 +106,7 @@ const AutoType = {
}
logger.debug('Obfuscated');
}
runner.run(err => {
runner.run((err) => {
this.running = false;
if (err) {
logger.error('Run error', err);
@@ -110,7 +114,7 @@ const AutoType = {
}
logger.debug('Complete', logger.ts(ts));
return callback && callback();
});
}, windowId);
});
} catch (ex) {
this.running = false;
@@ -123,7 +127,7 @@ const AutoType = {
try {
const parser = new AutoTypeParser(sequence);
const runner = parser.parse();
runner.resolve(entry, callback);
runner.resolve(entry, null, callback);
} catch (ex) {
return callback(ex);
}
@@ -158,97 +162,151 @@ const AutoType = {
}
},
getActiveWindowTitle(callback) {
logger.debug('Get window title');
return this.helper.getActiveWindowTitle((err, title, url) => {
getActiveWindowInfo(callback) {
logger.debug('Getting window info');
const helper = new AutoTypeHelper();
return helper.getActiveWindowInfo((err, windowInfo) => {
if (err) {
logger.error('Error get window title', err);
logger.error('Error getting window info', err);
} else {
if (!url) {
if (!windowInfo.url) {
// try to find a URL in the title
const urlMatcher = new RegExp(
'https?:\\/\\/(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{2,256}\\.[a-z]{2,4}\\b([-a-zA-Z0-9@:%_\\+.~#?&//=]*)'
);
const urlMatches = urlMatcher.exec(title);
url = urlMatches && urlMatches.length > 0 ? urlMatches[0] : null;
const urlMatcher = /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\\+~#=]{2,256}\.[a-z]{2,4}\b([-a-zA-Z0-9@:%_\\+.~#?&\/=]*)/;
const urlMatches = urlMatcher.exec(windowInfo.title);
windowInfo.url = urlMatches && urlMatches.length > 0 ? urlMatches[0] : null;
}
logger.debug('Window title', title, url);
logger.debug('Window info', windowInfo.id, windowInfo.title, windowInfo.url);
}
return callback(err, title, url);
return callback(err, windowInfo);
});
},
activeWindowMatches(windowInfo, callback) {
if (!windowInfo || !windowInfo.id) {
logger.debug('Skipped active window check because window id is unknown');
return callback(true);
}
this.getActiveWindowInfo((err, activeWindowInfo) => {
if (!activeWindowInfo) {
logger.debug('Error during active window check, something is wrong', err);
return callback(false);
}
if (activeWindowInfo.id !== windowInfo.id && !this.supportsEventsWithWindowId) {
logger.info(
`Active window doesn't match: ID is different. ` +
`Expected ${windowInfo.id}, got ${activeWindowInfo.id}`
);
return callback(false, activeWindowInfo);
}
if (activeWindowInfo.url !== windowInfo.url && !this.supportsEventsWithWindowId) {
logger.info(
`Active window doesn't match: url is different. ` +
`Expected "${windowInfo.url}", got "${activeWindowInfo.url}"`
);
return callback(false, activeWindowInfo);
}
logger.info('Active window matches');
callback(true, activeWindowInfo);
});
},
selectEntryAndRun() {
this.getActiveWindowTitle((e, title, url) => {
const filter = new AutoTypeFilter({title, url}, this.appModel);
const evt = { filter };
if (!this.appModel.files.hasOpenFiles()) {
this.pendingEvent = evt;
this.appModel.files.once('update', this.processPendingEvent, this);
this.getActiveWindowInfo(async (e, windowInfo) => {
const filter = new SelectEntryFilter(
windowInfo,
AppModel.instance,
AppModel.instance.files,
{
autoType: true
}
);
const evt = { filter, windowInfo };
if (!AppModel.instance.files.hasOpenFiles()) {
logger.debug('auto-type event delayed');
this.focusMainWindow();
} else {
this.processEventWithFilter(evt);
try {
await AppModel.instance.unlockAnyFile('autoTypeUnlockMessage');
} catch {
logger.debug('auto-type event canceled');
return;
}
if (this.selectEntryView) {
this.selectEntryView.show();
}
}
logger.debug('processing auto-type event');
this.processEventWithFilter(evt);
});
},
focusMainWindow() {
setTimeout(() => Launcher.showMainWindow(), Timeouts.RedrawInactiveWindow);
if (!Launcher.isAppFocused()) {
setTimeout(() => Launcher.showMainWindow(), Timeouts.RedrawInactiveWindow);
}
},
processEventWithFilter(evt) {
const entries = evt.filter.getEntries();
if (entries.length === 1 && AppSettingsModel.instance.get('directAutotype')) {
let entries = evt.filter.getEntries();
if (entries.length === 1 && AppSettingsModel.directAutotype) {
this.hideWindow(() => {
this.runAndHandleResult({ entry: entries.at(0) });
this.runAndHandleResult({ entry: entries[0] }, evt.windowInfo.id);
});
return;
}
this.focusMainWindow();
evt.filter.ignoreWindowInfo = true;
this.selectEntryView = new AutoTypeSelectView({
model: { filter: evt.filter }
}).render();
this.selectEntryView.on('result', result => {
if (entries.length === 0) {
if (evt.filter.useUrl) {
evt.filter.useUrl = false;
if (evt.filter.title && AppSettingsModel.autoTypeTitleFilterEnabled) {
evt.filter.useTitle = true;
}
}
entries = evt.filter.getEntries();
if (entries.length === 0 && evt.filter.useTitle) {
evt.filter.useTitle = false;
}
}
const humanReadableTarget = evt.filter.title || evt.filter.url;
const topMessage = humanReadableTarget
? Locale.autoTypeMsgMatchedByWindow.replace('{}', humanReadableTarget)
: Locale.autoTypeMsgNoWindow;
this.selectEntryView = new SelectEntryView({
isAutoType: true,
itemOptions: true,
filter: evt.filter,
topMessage
});
this.selectEntryView.on('result', (result) => {
logger.debug('Entry selected', result);
this.selectEntryView.off('result');
this.selectEntryView.remove();
this.selectEntryView = null;
this.hideWindow(() => {
if (result) {
this.runAndHandleResult(result);
if (result?.entry) {
this.activeWindowMatches(evt.windowInfo, (matches, activeWindowInfo) => {
if (matches) {
this.runAndHandleResult(result, evt.windowInfo.id);
}
});
}
});
});
this.selectEntryView.on('show-open-files', () => {
this.selectEntryView.render();
this.selectEntryView.on('show-open-files', async () => {
this.selectEntryView.hide();
Backbone.trigger('open-file');
Backbone.once('closed-open-view', () => {
this.selectEntryView.show();
this.selectEntryView.setupKeys();
}, this);
try {
await AppModel.instance.unlockAnyFile('autoTypeUnlockMessage');
} catch {
this.selectEntryView.emit('result', undefined);
return;
}
this.selectEntryView.show();
this.selectEntryView.render();
});
},
resetPendingEvent() {
if (this.pendingEvent) {
this.pendingEvent = null;
this.appModel.files.off('update', this.processPendingEvent, this);
logger.debug('auto-type event cancelled');
}
},
processPendingEvent() {
if (!this.pendingEvent) {
return;
}
logger.debug('processing pending auto-type event');
const evt = this.pendingEvent;
this.appModel.files.off('update', this.processPendingEvent, this);
this.pendingEvent = null;
this.processEventWithFilter(evt);
}
};
module.exports = AutoType;
export { AutoType };
+6 -49
View File
@@ -1,51 +1,8 @@
const Backbone = require('backbone');
const EntryModel = require('../models/entry-model');
const Comparators = require('../util/comparators');
import { Collection } from 'framework/collection';
import { EntryModel } from 'models/entry-model';
const EntryCollection = Backbone.Collection.extend({
model: EntryModel,
class EntryCollection extends Collection {
static model = EntryModel;
}
comparator: null,
comparators: {
'none': null,
'title': Comparators.stringComparator('title', true),
'-title': Comparators.stringComparator('title', false),
'website': Comparators.stringComparator('url', true),
'-website': Comparators.stringComparator('url', false),
'user': Comparators.stringComparator('user', true),
'-user': Comparators.stringComparator('user', false),
'created': Comparators.dateComparator('created', true),
'-created': Comparators.dateComparator('created', false),
'updated': Comparators.dateComparator('updated', true),
'-updated': Comparators.dateComparator('updated', false),
'-attachments': function(x, y) { return this.attachmentSortVal(x).localeCompare(this.attachmentSortVal(y)); },
'-rank': Comparators.rankComparator()
},
defaultComparator: 'title',
filter: null,
initialize: function(models, options) {
const comparatorName = options && options.comparator || this.defaultComparator;
this.comparator = this.comparators[comparatorName];
},
sortEntries: function(comparator, filter) {
this.filter = filter;
this.comparator = this.comparators[comparator] || this.comparators[this.defaultComparator];
this.sort();
},
attachmentSortVal: function(entry) {
const att = entry.attachments;
let str = att.length ? String.fromCharCode(64 + att.length) : 'Z';
if (att[0]) {
str += att[0].title;
}
return str;
}
});
module.exports = EntryCollection;
export { EntryCollection };
+20 -20
View File
@@ -1,24 +1,24 @@
const Backbone = require('backbone');
const FileModel = require('../models/file-model');
import { Collection } from 'framework/collection';
import { Model } from 'framework/model';
const FileCollection = Backbone.Collection.extend({
model: FileModel,
class FileCollection extends Collection {
static model = Model;
hasOpenFiles: function() {
return this.some(file => file.get('open'));
},
hasUnsavedFiles: function() {
return this.some(file => file.get('modified'));
},
hasDirtyFiles: function() {
return this.some(file => file.get('dirty'));
},
getByName: function(name) {
return this.find(file => file.get('name').toLowerCase() === name.toLowerCase());
hasOpenFiles() {
return this.some((file) => file.active);
}
});
module.exports = FileCollection;
hasUnsavedFiles() {
return this.some((file) => file.modified);
}
hasDirtyFiles() {
return this.some((file) => file.dirty);
}
getByName(name) {
return this.find((file) => file.name.toLowerCase() === name.toLowerCase());
}
}
export { FileCollection };
+31 -34
View File
@@ -1,42 +1,39 @@
const Backbone = require('backbone');
const FileInfoModel = require('../models/file-info-model');
const SettingsStore = require('../comp/settings-store');
import { Collection } from 'framework/collection';
import { SettingsStore } from 'comp/settings/settings-store';
import { FileInfoModel } from 'models/file-info-model';
const FileInfoCollection = Backbone.Collection.extend({
model: FileInfoModel,
class FileInfoCollection extends Collection {
static model = FileInfoModel;
initialize: function () {
},
load: function () {
return SettingsStore.load('file-info').then(data => {
load() {
return SettingsStore.load('file-info').then((data) => {
if (data) {
this.reset(data, {silent: true});
for (const item of data) {
this.push(new FileInfoModel(item));
}
}
});
},
save: function () {
SettingsStore.save('file-info', this.toJSON());
},
getLast: function () {
return this.first();
},
getMatch: function (storage, name, path) {
return this.find(fi => {
return (fi.get('storage') || '') === (storage || '') &&
(fi.get('name') || '') === (name || '') &&
(fi.get('path') || '') === (path || '');
});
},
getByName: function(name) {
return this.find(file => file.get('name').toLowerCase() === name.toLowerCase());
}
});
FileInfoCollection.instance = new FileInfoCollection();
save() {
SettingsStore.save('file-info', this);
}
module.exports = FileInfoCollection;
getMatch(storage, name, path) {
return this.find((fi) => {
return (
(fi.storage || '') === (storage || '') &&
(fi.name || '') === (name || '') &&
(fi.path || '') === (path || '')
);
});
}
getByName(name) {
return this.find((file) => file.name.toLowerCase() === name.toLowerCase());
}
}
const instance = new FileInfoCollection();
export { instance as FileInfoCollection };
+6 -6
View File
@@ -1,8 +1,8 @@
const Backbone = require('backbone');
const GroupModel = require('../models/group-model');
import { Collection } from 'framework/collection';
import { GroupModel } from 'models/group-model';
const GroupCollection = Backbone.Collection.extend({
model: GroupModel
});
class GroupCollection extends Collection {
static model = GroupModel;
}
module.exports = GroupCollection;
export { GroupCollection };
@@ -1,8 +1,8 @@
const Backbone = require('backbone');
const MenuItemModel = require('../../models/menu/menu-item-model');
import { Collection } from 'framework/collection';
import { MenuItemModel } from 'models/menu/menu-item-model';
const MenuItemCollection = Backbone.Collection.extend({
model: MenuItemModel
});
class MenuItemCollection extends Collection {
static model = MenuItemModel;
}
module.exports = MenuItemCollection;
export { MenuItemCollection };
@@ -1,8 +1,8 @@
const Backbone = require('backbone');
const MenuOptionModel = require('../../models/menu/menu-option-model');
import { Collection } from 'framework/collection';
import { MenuOptionModel } from 'models/menu/menu-option-model';
const MenuOptionCollection = Backbone.Collection.extend({
model: MenuOptionModel
});
class MenuOptionCollection extends Collection {
static model = MenuOptionModel;
}
module.exports = MenuOptionCollection;
export { MenuOptionCollection };
@@ -1,8 +1,8 @@
const Backbone = require('backbone');
const MenuSectionModel = require('../../models/menu/menu-section-model');
import { Collection } from 'framework/collection';
import { MenuSectionModel } from 'models/menu/menu-section-model';
const MenuSectionCollection = Backbone.Collection.extend({
model: MenuSectionModel
});
class MenuSectionCollection extends Collection {
static model = MenuSectionModel;
}
module.exports = MenuSectionCollection;
export { MenuSectionCollection };
@@ -0,0 +1,52 @@
import { Collection } from 'framework/collection';
import { Model } from 'framework/model';
import { Comparators } from 'util/data/comparators';
class SearchResultCollection extends Collection {
static model = Model;
comparators = {
'none': null,
'title': Comparators.stringComparator('title', true),
'-title': Comparators.stringComparator('title', false),
'website': Comparators.stringComparator('url', true),
'-website': Comparators.stringComparator('url', false),
'user': Comparators.stringComparator('user', true),
'-user': Comparators.stringComparator('user', false),
'created': Comparators.dateComparator('created', true),
'-created': Comparators.dateComparator('created', false),
'updated': Comparators.dateComparator('updated', true),
'-updated': Comparators.dateComparator('updated', false),
'-attachments': (x, y) => {
return this.attachmentSortVal(x).localeCompare(this.attachmentSortVal(y));
},
'-rank': Comparators.rankComparator().bind(this)
};
defaultComparator = 'title';
entryFilter = null;
constructor(models, options) {
super(models);
const comparatorName = (options && options.comparator) || this.defaultComparator;
this.comparator = this.comparators[comparatorName];
}
sortEntries(comparator, filter) {
this.entryFilter = filter;
this.comparator = this.comparators[comparator] || this.comparators[this.defaultComparator];
this.sort();
}
attachmentSortVal(entry) {
const att = entry.attachments;
let str = att.length ? String.fromCharCode(64 + att.length) : 'Z';
if (att[0]) {
str += att[0].title;
}
return str;
}
}
export { SearchResultCollection };
@@ -1,23 +1,23 @@
const FeatureDetector = require('../util/feature-detector');
const Alerts = require('../comp/alerts');
const AppSettingsModel = require('../models/app-settings-model');
const Launcher = require('./launcher');
const Locale = require('../util/locale');
import { Launcher } from 'comp/launcher';
import { Alerts } from 'comp/ui/alerts';
import { AppSettingsModel } from 'models/app-settings-model';
import { Features } from 'util/features';
import { Locale } from 'util/locale';
const AppRightsChecker = {
AppPath: '/Applications/KeeWeb.app',
init() {
if (!FeatureDetector.isDesktop || !FeatureDetector.isMac) {
if (!Features.isDesktop || !Features.isMac) {
return;
}
if (AppSettingsModel.instance.get('skipFolderRightsWarning')) {
if (AppSettingsModel.skipFolderRightsWarning) {
return;
}
if (!Launcher.getAppPath().startsWith(this.AppPath)) {
return;
}
this.needRunInstaller(needRun => {
this.needRunInstaller((needRun) => {
if (needRun) {
this.showAlert();
this.runInstaller();
@@ -26,7 +26,7 @@ const AppRightsChecker = {
},
needRunInstaller(callback) {
Launcher.statFile(this.AppPath, stat => {
Launcher.statFile(this.AppPath, (stat) => {
const folderIsRoot = stat && stat.uid === 0;
callback(!folderIsRoot);
});
@@ -37,10 +37,13 @@ const AppRightsChecker = {
this.alert = Alerts.alert({
icon: 'lock',
header: Locale.appRightsAlert,
body: Locale.appRightsAlertBody1.replace('{}', `<code>${this.AppPath}</code>`) +
'<br/>' + Locale.appRightsAlertBody2 + `: <pre>${command}</pre>`,
body:
Locale.appRightsAlertBody1.replace('{}', this.AppPath) +
'\n' +
Locale.appRightsAlertBody2,
pre: command,
buttons: [
{result: 'skip', title: Locale.alertDoNotAsk, error: true},
{ result: 'skip', title: Locale.alertDoNotAsk, error: true },
Alerts.buttons.ok
],
success: (result) => {
@@ -54,9 +57,10 @@ const AppRightsChecker = {
runInstaller() {
Launcher.spawn({
cmd: this.AppPath + '/Contents/Installer/KeeWeb\ Installer.app/Contents/MacOS/applet',
cmd: this.AppPath + '/Contents/Installer/KeeWeb Installer.app/Contents/MacOS/applet',
args: ['--install'],
complete: () => {
this.needRunInstaller(needRun => {
this.needRunInstaller((needRun) => {
if (this.alert && !needRun) {
this.alert.closeWithResult('cancel');
}
@@ -66,12 +70,12 @@ const AppRightsChecker = {
},
dontAskAnymore() {
this.needRunInstaller(needRun => {
this.needRunInstaller((needRun) => {
if (needRun) {
AppSettingsModel.instance.set('skipFolderRightsWarning', true);
AppSettingsModel.skipFolderRightsWarning = true;
}
});
}
};
module.exports = AppRightsChecker;
export { AppRightsChecker };
@@ -0,0 +1,194 @@
import { Events } from 'framework/events';
import { Logger } from 'util/logger';
import { YubiKey } from 'comp/app/yubikey';
import { UsbListener } from 'comp/app/usb-listener';
import { Alerts } from 'comp/ui/alerts';
import { Locale } from 'util/locale';
import { Timeouts } from 'const/timeouts';
import { Launcher } from 'comp/launcher';
import { AppSettingsModel } from 'models/app-settings-model';
const logger = new Logger('chal-resp');
const ChalRespCalculator = {
cache: {},
getCacheKey(params) {
return `${params.vid}:${params.pid}:${params.serial}:${params.slot}`;
},
build(params) {
if (!params) {
return null;
}
return (challenge) => {
return new Promise((resolve, reject) => {
challenge = Buffer.from(challenge);
const hexChallenge = challenge.toString('hex');
const cacheKey = this.getCacheKey(params);
const respFromCache = this.cache[cacheKey]?.[hexChallenge];
if (respFromCache) {
logger.debug('Found ChalResp in cache');
return resolve(Buffer.from(respFromCache, 'hex'));
}
if (!AppSettingsModel.enableUsb) {
logger.debug('USB is disabled');
Alerts.error({
header: Locale.yubiKeyDisabledErrorHeader,
body: Locale.yubiKeyDisabledErrorBody,
complete() {
const err = new Error(Locale.yubiKeyDisabledErrorHeader);
err.userCanceled = true;
err.ykError = true;
reject(err);
}
});
return;
}
logger.debug('Calculating ChalResp using a YubiKey', params);
this._calc(params, challenge, (err, response) => {
if (err) {
return reject(err);
}
resolve(response);
});
});
};
},
_calc(params, challenge, callback) {
let touchAlert = null;
let userCanceled = false;
YubiKey.calculateChalResp(params, challenge, (err, response) => {
if (userCanceled) {
userCanceled = false;
return;
}
if (touchAlert) {
touchAlert.closeWithoutResult();
touchAlert = null;
}
if (err) {
if (err.noKey) {
logger.info('YubiKey ChalResp: no key');
this._showNoKeyAlert(params.serial, (err) => {
if (err) {
return callback(err);
}
this._calc(params, challenge, callback);
});
return;
} else if (err.touchRequested) {
logger.info('YubiKey ChalResp: touch requested');
touchAlert = this._showTouchAlert(params.serial, (err) => {
touchAlert = null;
userCanceled = true;
logger.info('YubiKey ChalResp canceled');
YubiKey.cancelChalResp();
callback(err);
});
return;
} else {
logger.error('YubiKey ChalResp error', err);
}
return callback(err);
}
const cacheKey = this.getCacheKey(params);
if (!this.cache[cacheKey]) {
this.cache[cacheKey] = {};
}
const hexChallenge = challenge.toString('hex');
this.cache[cacheKey][hexChallenge] = response.toString('hex');
logger.info('Calculated YubiKey ChalResp');
callback(null, response);
});
},
_showNoKeyAlert(serial, callback) {
Launcher.showMainWindow();
let noKeyAlert = null;
let deviceEnumerationTimer;
const onUsbDevicesChanged = () => {
if (!UsbListener.attachedYubiKeys) {
return;
}
deviceEnumerationTimer = setTimeout(() => {
YubiKey.list((err, list) => {
if (err) {
logger.error('YubiKey list error', err);
return;
}
const isAttached = list.some((yk) => yk.serial === serial);
logger.info(isAttached ? 'YubiKey found' : 'YubiKey not found');
if (isAttached) {
Events.off('usb-devices-changed', onUsbDevicesChanged);
if (noKeyAlert) {
noKeyAlert.closeWithoutResult();
}
callback();
}
});
}, Timeouts.ExternalDeviceAfterReconnect);
};
Events.on('usb-devices-changed', onUsbDevicesChanged);
noKeyAlert = Alerts.alert({
header: Locale.yubiKeyNoKeyHeader,
body: Locale.yubiKeyNoKeyBody.replace('{}', serial),
buttons: [Alerts.buttons.cancel],
icon: 'usb-token',
cancel: () => {
logger.info('No key alert closed');
clearTimeout(deviceEnumerationTimer);
Events.off('usb-devices-changed', onUsbDevicesChanged);
const err = new Error('User canceled the YubiKey no key prompt');
err.userCanceled = true;
err.ykError = true;
return callback(err);
}
});
},
_showTouchAlert(serial, callback) {
Launcher.showMainWindow();
return Alerts.alert({
header: Locale.yubiKeyTouchRequestedHeader,
body: Locale.yubiKeyTouchRequestedBody.replace('{}', serial),
buttons: [Alerts.buttons.cancel],
icon: 'usb-token',
cancel: () => {
logger.info('Touch alert closed');
const err = new Error('User canceled the YubiKey touch prompt');
err.userCanceled = true;
err.ykError = true;
return callback(err);
}
});
},
clearCache(params) {
delete this.cache[this.getCacheKey(params)];
}
};
export { ChalRespCalculator };
@@ -2,4 +2,4 @@ const DragDropInfo = {
dragObject: null
};
module.exports = DragDropInfo;
export { DragDropInfo };
@@ -1,20 +1,21 @@
const AppSettingsModel = require('../models/app-settings-model');
import { AppSettingsModel } from 'models/app-settings-model';
import { UrlFormat } from 'util/formatting/url-format';
const ChooserAppKey = 'qp7ctun6qt5n9d6';
const DropboxChooser = function(callback) {
const DropboxChooser = function (callback) {
this.cb = callback;
this.onMessage = this.onMessage.bind(this);
};
DropboxChooser.prototype.callback = function(err, res) {
DropboxChooser.prototype.callback = function (err, res) {
if (this.cb) {
this.cb(err, res);
}
this.cb = null;
};
DropboxChooser.prototype.choose = function() {
DropboxChooser.prototype.choose = function () {
const windowFeatures = 'width=640,height=552,left=357,top=100,resizable=yes,location=yes';
const url = this.buildUrl();
this.popup = window.open(url, 'dropbox', windowFeatures);
@@ -25,10 +26,10 @@ DropboxChooser.prototype.choose = function() {
this.closeInt = setInterval(this.checkClose.bind(this), 200);
};
DropboxChooser.prototype.buildUrl = function() {
const urlParams = {
origin: encodeURIComponent(window.location.protocol + '//' + window.location.host),
'app_key': AppSettingsModel.instance.get('dropboxAppKey') || ChooserAppKey,
DropboxChooser.prototype.buildUrl = function () {
return UrlFormat.makeUrl('https://www.dropbox.com/chooser', {
origin: window.location.protocol + '//' + window.location.host,
'app_key': AppSettingsModel.dropboxAppKey || ChooserAppKey,
'link_type': 'direct',
trigger: 'js',
multiselect: 'false',
@@ -36,12 +37,11 @@ DropboxChooser.prototype.buildUrl = function() {
folderselect: 'false',
iframe: 'false',
version: 2
};
return 'https://www.dropbox.com/chooser?' + Object.keys(urlParams).map(key => key + '=' + urlParams[key]).join('&');
});
};
DropboxChooser.prototype.onMessage = function(e) {
if (e.source !== this.popup) {
DropboxChooser.prototype.onMessage = function (e) {
if (e.source !== this.popup || e.origin !== 'https://www.dropbox.com') {
return;
}
const data = JSON.parse(e.data);
@@ -69,7 +69,7 @@ DropboxChooser.prototype.onMessage = function(e) {
}
};
DropboxChooser.prototype.checkClose = function() {
DropboxChooser.prototype.checkClose = function () {
if (this.popup.closed) {
clearInterval(this.closeInt);
window.removeEventListener('message', this.onMessage);
@@ -79,7 +79,7 @@ DropboxChooser.prototype.checkClose = function() {
}
};
DropboxChooser.prototype.success = function(params) {
DropboxChooser.prototype.success = function (params) {
if (!params || !params[0] || !params[0].link || params[0].is_dir) {
return this.callback('bad result');
}
@@ -87,7 +87,7 @@ DropboxChooser.prototype.success = function(params) {
this.readFile(this.result.link);
};
DropboxChooser.prototype.readFile = function(url) {
DropboxChooser.prototype.readFile = function (url) {
const xhr = new XMLHttpRequest();
xhr.addEventListener('load', () => {
this.callback(null, { name: this.result.name, data: xhr.response });
@@ -99,4 +99,4 @@ DropboxChooser.prototype.readFile = function(url) {
xhr.send();
};
module.exports = DropboxChooser;
export { DropboxChooser };
+29
View File
@@ -0,0 +1,29 @@
import { AppSettingsModel } from 'models/app-settings-model';
import { RuntimeDataModel } from 'models/runtime-data-model';
const ExportApi = {
settings: {
get(key) {
return key ? AppSettingsModel[key] : { ...AppSettingsModel };
},
set(key, value) {
AppSettingsModel[key] = value;
},
del(key) {
delete AppSettingsModel[key];
}
},
runtimeData: {
get(key) {
return key ? RuntimeDataModel[key] : { ...RuntimeDataModel };
},
set(key, value) {
RuntimeDataModel[key] = value;
},
del(key) {
delete RuntimeDataModel[key];
}
}
};
export { ExportApi };
+18
View File
@@ -0,0 +1,18 @@
import { Logger } from 'util/logger';
const logger = new Logger(
'focus-manager',
undefined,
localStorage.debugFocusManager ? Logger.Level.Debug : Logger.Level.Info
);
const FocusManager = {
modal: null,
setModal(modal) {
this.modal = modal;
logger.debug('Set modal', modal);
}
};
export { FocusManager };
+177
View File
@@ -0,0 +1,177 @@
import { AppSettingsModel } from 'models/app-settings-model';
import { Locale } from 'util/locale';
const GeneratorPresets = {
get defaultPreset() {
return {
name: 'Default',
title: Locale.genPresetDefault,
length: 16,
upper: true,
lower: true,
digits: true
};
},
get browserExtensionPreset() {
return {
name: 'BrowserExtension',
length: 20,
upper: true,
lower: true,
special: true,
brackets: true,
ambiguous: true
};
},
get builtIn() {
return [
this.defaultPreset,
{
name: 'Pronounceable',
title: Locale.genPresetPronounceable,
length: 10,
lower: true,
upper: true
},
{
name: 'Med',
title: Locale.genPresetMed,
length: 16,
upper: true,
lower: true,
digits: true,
special: true,
brackets: true,
ambiguous: true
},
{
name: 'Long',
title: Locale.genPresetLong,
length: 32,
upper: true,
lower: true,
digits: true
},
{ name: 'Pin4', title: Locale.genPresetPin4, length: 4, digits: true },
{
name: 'Mac',
title: Locale.genPresetMac,
length: 17,
include: '0123456789ABCDEF',
pattern: 'XX-'
},
{
name: 'Hash128',
title: Locale.genPresetHash128,
length: 32,
include: '0123456789abcdef'
},
{
name: 'Hash256',
title: Locale.genPresetHash256,
length: 64,
include: '0123456789abcdef'
}
];
},
get all() {
let presets = this.builtIn;
presets.forEach((preset) => {
preset.builtIn = true;
});
const setting = AppSettingsModel.generatorPresets;
if (setting) {
if (setting.user) {
presets = presets.concat(setting.user.map((item) => ({ ...item })));
}
let hasDefault = false;
presets.forEach((preset) => {
if (setting.disabled && setting.disabled[preset.name]) {
preset.disabled = true;
}
if (setting.default === preset.name) {
hasDefault = true;
preset.default = true;
}
});
if (!hasDefault) {
presets[0].default = true;
}
}
return presets;
},
get enabled() {
const allPresets = this.all.filter((preset) => !preset.disabled);
if (!allPresets.length) {
allPresets.push(this.defaultPreset);
}
return allPresets;
},
getOrCreateSetting() {
let setting = AppSettingsModel.generatorPresets;
if (!setting) {
setting = { user: [] };
}
return setting;
},
add(preset) {
const setting = this.getOrCreateSetting();
if (preset.name && !setting.user.filter((p) => p.name === preset.name).length) {
setting.user.push(preset);
this.save(setting);
}
},
remove(name) {
const setting = this.getOrCreateSetting();
setting.user = setting.user.filter((p) => p.name !== name);
this.save(setting);
},
setPreset(name, props) {
const setting = this.getOrCreateSetting();
const preset = setting.user.filter((p) => p.name === name)[0];
if (preset) {
Object.assign(preset, props);
this.save(setting);
}
},
setDisabled(name, disabled) {
const setting = this.getOrCreateSetting();
if (disabled) {
if (!setting.disabled) {
setting.disabled = {};
}
setting.disabled[name] = true;
} else {
if (setting.disabled) {
delete setting.disabled[name];
}
}
this.save(setting);
},
setDefault(name) {
const setting = this.getOrCreateSetting();
if (name) {
setting.default = name;
} else {
delete setting.default;
}
this.save(setting);
},
save(setting) {
AppSettingsModel.set({ generatorPresets: undefined }, { silent: true });
AppSettingsModel.generatorPresets = setting;
}
};
export { GeneratorPresets };
@@ -0,0 +1,37 @@
import * as kdbxweb from 'kdbxweb';
import { Logger } from 'util/logger';
const logger = new Logger('online-password-checker');
const exposedPasswords = {};
function checkIfPasswordIsExposedOnline(password) {
if (!password || !password.isProtected || !password.byteLength) {
return false;
}
const saltedValue = password.saltedValue();
const cached = exposedPasswords[saltedValue];
if (cached !== undefined) {
return cached;
}
const passwordBytes = password.getBinary();
return crypto.subtle
.digest({ name: 'SHA-1' }, passwordBytes)
.then((sha1) => {
kdbxweb.ByteUtils.zeroBuffer(passwordBytes);
sha1 = kdbxweb.ByteUtils.bytesToHex(sha1).toUpperCase();
const shaFirst = sha1.substr(0, 5);
return fetch(`https://api.pwnedpasswords.com/range/${shaFirst}`)
.then((response) => response.text())
.then((response) => {
const isPresent = response.includes(sha1.substr(5));
exposedPasswords[saltedValue] = isPresent;
return isPresent;
});
})
.catch((e) => {
logger.error('Error checking password online', e);
});
}
export { checkIfPasswordIsExposedOnline };
@@ -0,0 +1,99 @@
import { SearchResultCollection } from 'collections/search-result-collection';
import { Ranking } from 'util/data/ranking';
const urlPartsRegex = /^(\w+:\/\/)?(?:(?:www|wwws|secure)\.)?([^\/]+)\/?(.*)/;
class SelectEntryFilter {
constructor(windowInfo, appModel, files, filterOptions) {
this.title = windowInfo.title;
this.useTitle = !!windowInfo.title && !windowInfo.url;
this.url = windowInfo.url;
this.useUrl = !!windowInfo.url;
this.subdomains = true;
this.text = '';
this.appModel = appModel;
this.files = files;
this.filterOptions = filterOptions;
}
getEntries() {
const filter = {
text: this.text,
...this.filterOptions
};
let entries = this.appModel
.getEntriesByFilter(filter, this.files)
.map((e) => [e, this._getEntryRank(e)]);
if (this.useUrl || this.useTitle) {
entries = entries.filter((e) => e[1]);
}
entries = entries.sort((x, y) =>
x[1] === y[1] ? x[0].title.localeCompare(y[0].title) : y[1] - x[1]
);
entries = entries.map((p) => p[0]);
return new SearchResultCollection(entries, { comparator: 'none' });
}
_getEntryRank(entry) {
let titleRank = 0;
let urlRank = 0;
if (this.useTitle && this.title && entry.title) {
titleRank = Ranking.getStringRank(entry.title.toLowerCase(), this.title.toLowerCase());
if (!titleRank) {
return 0;
}
}
if (this.useUrl && this.url) {
const searchUrlLower = this.url.toLowerCase();
const searchUrlParts = urlPartsRegex.exec(searchUrlLower);
for (const url of entry.getAllUrls()) {
const entryUrlParts = urlPartsRegex.exec(url.toLowerCase());
if (entryUrlParts) {
const [, scheme, domain, path] = entryUrlParts;
const [, searchScheme, searchDomain, searchPath] = searchUrlParts;
if (
domain === searchDomain ||
(this.subdomains && searchDomain.indexOf('.' + domain) > 0)
) {
if (domain === searchDomain) {
urlRank += 20;
} else {
urlRank += 10;
}
if (path === searchPath) {
urlRank += 10;
} else if (path && searchPath) {
if (path.lastIndexOf(searchPath, 0) === 0) {
urlRank += 5;
} else if (searchPath.lastIndexOf(path, 0) === 0) {
urlRank += 3;
}
}
if (scheme === searchScheme) {
urlRank += 1;
}
}
}
}
if (entry.searchText.includes(searchUrlLower)) {
// the url is in some field; include it
urlRank += 5;
}
}
if (this.useTitle && !titleRank) {
return 0;
}
if (this.useUrl && !urlRank) {
return 0;
}
return titleRank + urlRank;
}
}
export { SelectEntryFilter };
+138
View File
@@ -0,0 +1,138 @@
import { Launcher } from 'comp/launcher';
import { Keys } from 'const/keys';
import { AppSettingsModel } from 'models/app-settings-model';
import { Features } from 'util/features';
import { StringFormat } from 'util/formatting/string-format';
import { Locale } from 'util/locale';
let allowedKeys;
function getAllowedKeys() {
if (!allowedKeys) {
allowedKeys = {};
for (const [name, code] of Object.entries(Keys)) {
const keyName = name.replace('DOM_VK_', '');
if (/^([0-9A-Z]|F\d{1,2})$/.test(keyName)) {
allowedKeys[code] = keyName;
}
}
}
return allowedKeys;
}
const globalShortcuts = {
copyPassword: { mac: 'Ctrl+Alt+C', all: 'Shift+Alt+C' },
copyUser: { mac: 'Ctrl+Alt+B', all: 'Shift+Alt+B' },
copyUrl: { mac: 'Ctrl+Alt+U', all: 'Shift+Alt+U' },
copyOtp: {},
autoType: { mac: 'Ctrl+Alt+T', all: 'Shift+Alt+T' },
restoreApp: {}
};
const Shortcuts = {
keyEventToShortcut(event) {
const modifiers = [];
if (event.ctrlKey) {
modifiers.push('Ctrl');
}
if (event.altKey) {
modifiers.push('Alt');
}
if (event.shiftKey) {
modifiers.push('Shift');
}
if (Features.isMac && event.metaKey) {
modifiers.push('Meta');
}
const keyName = getAllowedKeys()[event.which];
return {
value: modifiers.join('+') + '+' + (keyName || '…'),
valid: modifiers.length > 0 && !!keyName
};
},
presentShortcut(shortcutValue, formatting) {
if (!shortcutValue) {
return '-';
}
return shortcutValue
.split(/\+/g)
.map((part) => {
switch (part) {
case 'Ctrl':
return this.ctrlShortcutSymbol(formatting);
case 'Alt':
return this.altShortcutSymbol(formatting);
case 'Shift':
return this.shiftShortcutSymbol(formatting);
case 'Meta':
return this.actionShortcutSymbol(formatting);
default:
return part;
}
})
.join('');
},
actionShortcutSymbol(formatting) {
return Features.isMac ? '⌘' : this.formatShortcut(Locale.ctrlKey, formatting);
},
altShortcutSymbol(formatting) {
return Features.isMac ? '⌥' : this.formatShortcut(Locale.altKey, formatting);
},
shiftShortcutSymbol(formatting) {
return Features.isMac ? '⇧' : this.formatShortcut(Locale.shiftKey, formatting);
},
ctrlShortcutSymbol(formatting) {
return Features.isMac ? '⌃' : this.formatShortcut(Locale.ctrlKey, formatting);
},
formatShortcut(shortcut, formatting) {
return formatting ? `${shortcut} + ` : `${shortcut}+`;
},
globalShortcutText(type, formatting) {
return this.presentShortcut(this.globalShortcut(type), formatting);
},
globalShortcut(type) {
const appSettingsShortcut = AppSettingsModel[this.globalShortcutAppSettingsKey(type)];
if (appSettingsShortcut) {
return appSettingsShortcut;
}
const globalShortcut = globalShortcuts[type];
if (globalShortcut) {
if (Features.isMac && globalShortcut.mac) {
return globalShortcut.mac;
}
return globalShortcut.all;
}
return undefined;
},
setGlobalShortcut(type, value) {
if (!globalShortcuts[type]) {
throw new Error('Bad shortcut: ' + type);
}
if (value) {
AppSettingsModel[this.globalShortcutAppSettingsKey(type)] = value;
} else {
delete AppSettingsModel[this.globalShortcutAppSettingsKey(type)];
}
Launcher.setGlobalShortcuts(AppSettingsModel);
},
globalShortcutAppSettingsKey(type) {
return 'globalShortcut' + StringFormat.capFirst(type);
},
screenshotToClipboardShortcut() {
if (Features.isiOS) {
return 'Sleep+Home';
}
if (Features.isMobile) {
return '';
}
if (Features.isMac) {
return 'Command-Shift-Control-4';
}
if (Features.isWindows) {
return 'Alt+PrintScreen';
}
return '';
}
};
export { Shortcuts };
@@ -1,5 +1,5 @@
const Backbone = require('backbone');
const Launcher = require('./launcher');
import { Events } from 'framework/events';
import { Launcher } from 'comp/launcher';
const LocalStorageKeyName = 'instanceCheck';
const LocalStorageResponseKeyName = 'instanceMaster';
@@ -7,7 +7,7 @@ const LocalStorageResponseKeyName = 'instanceMaster';
const instanceKey = Date.now().toString();
const SingleInstanceChecker = {
init: function() {
init() {
if (Launcher) {
return;
}
@@ -15,24 +15,29 @@ const SingleInstanceChecker = {
SingleInstanceChecker.setKey(LocalStorageKeyName, instanceKey);
},
storageChanged: function(e) {
storageChanged(e) {
if (!e.newValue) {
return;
}
if (e.key === LocalStorageKeyName && e.newValue !== instanceKey) {
SingleInstanceChecker.setKey(LocalStorageResponseKeyName, instanceKey + Math.random().toString());
SingleInstanceChecker.setKey(
LocalStorageResponseKeyName,
instanceKey + Math.random().toString()
);
} else if (e.key === LocalStorageResponseKeyName && e.newValue.indexOf(instanceKey) < 0) {
window.removeEventListener('storage', SingleInstanceChecker.storageChanged);
Backbone.trigger('second-instance');
Events.emit('second-instance');
}
},
setKey: function(key, value) {
setKey(key, value) {
try {
localStorage.setItem(key, value);
setTimeout(() => { localStorage.removeItem(key); }, 100);
setTimeout(() => {
localStorage.removeItem(key);
}, 100);
} catch (e) {}
}
};
module.exports = SingleInstanceChecker;
export { SingleInstanceChecker };
+54
View File
@@ -0,0 +1,54 @@
import { Logger } from 'util/logger';
const logger = new Logger('start-profiler');
let lastTs = 0;
const operations = [];
const StartProfiler = {
milestone(name) {
const ts = logger.ts();
const elapsed = ts - lastTs;
lastTs = ts;
operations.push({ name, elapsed });
},
report() {
const networkTime = this.getNetworkTime();
operations.unshift({ name: 'fetching', elapsed: networkTime });
const time = Math.round(performance.now());
this.printReport('App', operations, time);
},
reportAppProfile(data) {
this.printReport('Electron app', data.timings, data.totalTime);
},
printReport(name, operations, totalTime) {
const message =
`${name} started in ${totalTime}ms: ` +
operations.map((op) => `${op.name}=${Math.round(op.elapsed)}ms`).join(', ');
logger.info(message);
},
getNetworkTime() {
let perfEntry;
if (performance.getEntriesByType) {
[perfEntry] = performance.getEntriesByType('navigation');
}
if (!perfEntry || !perfEntry.responseEnd || !perfEntry.fetchStart) {
perfEntry = performance.timing;
}
return perfEntry.responseEnd - perfEntry.fetchStart;
}
};
StartProfiler.milestone('pre-init');
export { StartProfiler };
+306
View File
@@ -0,0 +1,306 @@
import * as kdbxweb from 'kdbxweb';
import { Events } from 'framework/events';
import { RuntimeInfo } from 'const/runtime-info';
import { Transport } from 'comp/browser/transport';
import { Launcher } from 'comp/launcher';
import { Links } from 'const/links';
import { AppSettingsModel } from 'models/app-settings-model';
import { UpdateModel } from 'models/update-model';
import { SemVer } from 'util/data/semver';
import { Logger } from 'util/logger';
import { SignatureVerifier } from 'util/data/signature-verifier';
const logger = new Logger('updater');
const Updater = {
UpdateInterval: 1000 * 60 * 60 * 24,
MinUpdateTimeout: 500,
MinUpdateSize: 10000,
nextCheckTimeout: null,
updateCheckDate: new Date(0),
enabled: Launcher?.updaterEnabled(),
getAutoUpdateType() {
if (!this.enabled) {
return false;
}
let autoUpdate = AppSettingsModel.autoUpdate;
if (autoUpdate && autoUpdate === true) {
autoUpdate = 'install';
}
return autoUpdate;
},
updateInProgress() {
return (
UpdateModel.status === 'checking' ||
['downloading', 'extracting', 'updating'].indexOf(UpdateModel.updateStatus) >= 0
);
},
init() {
this.scheduleNextCheck();
if (!Launcher && navigator.serviceWorker && !RuntimeInfo.beta && !RuntimeInfo.devMode) {
navigator.serviceWorker
.register('service-worker.js')
.then((reg) => {
logger.info('Service worker registered');
reg.addEventListener('updatefound', () => {
if (reg.active) {
logger.info('Service worker found an update');
UpdateModel.set({ updateStatus: 'ready' });
}
});
})
.catch((e) => {
logger.error('Failed to register a service worker', e);
});
}
},
scheduleNextCheck() {
if (this.nextCheckTimeout) {
clearTimeout(this.nextCheckTimeout);
this.nextCheckTimeout = null;
}
if (!this.getAutoUpdateType()) {
return;
}
let timeDiff = this.MinUpdateTimeout;
const lastCheckDate = UpdateModel.lastCheckDate;
if (lastCheckDate) {
timeDiff = Math.min(
Math.max(this.UpdateInterval + (lastCheckDate - new Date()), this.MinUpdateTimeout),
this.UpdateInterval
);
}
this.nextCheckTimeout = setTimeout(this.check.bind(this), timeDiff);
logger.info('Next update check will happen in ' + Math.round(timeDiff / 1000) + 's');
},
check(startedByUser) {
if (!this.enabled || this.updateInProgress()) {
return;
}
UpdateModel.set({ status: 'checking' });
if (!startedByUser) {
// additional protection from broken program logic, to ensure that auto-checks are not performed more than once an hour
const diffMs = new Date() - this.updateCheckDate;
if (isNaN(diffMs) || diffMs < 1000 * 60 * 60) {
logger.error(
'Prevented update check; last check was performed at ' + this.updateCheckDate
);
this.scheduleNextCheck();
return;
}
this.updateCheckDate = new Date();
}
logger.info('Checking for update...');
Transport.httpGet({
url: Links.UpdateJson,
json: true,
success: (updateJson) => {
const dt = new Date();
logger.info('Update check: ' + (updateJson.version || 'unknown'));
if (!updateJson.version) {
const errMsg = 'No version info found';
UpdateModel.set({
status: 'error',
lastCheckDate: dt,
lastCheckError: errMsg
});
UpdateModel.save();
this.scheduleNextCheck();
return;
}
const prevLastVersion = UpdateModel.lastVersion;
UpdateModel.set({
status: 'ok',
lastCheckDate: dt,
lastSuccessCheckDate: dt,
lastVersionReleaseDate: new Date(updateJson.date),
lastVersion: updateJson.version,
lastCheckError: null,
lastCheckUpdMin: updateJson.minVersion || null
});
UpdateModel.save();
this.scheduleNextCheck();
if (!this.canAutoUpdate()) {
return;
}
if (
prevLastVersion === UpdateModel.lastVersion &&
UpdateModel.updateStatus === 'ready'
) {
logger.info('Waiting for the user to apply downloaded update');
return;
}
if (!startedByUser && this.getAutoUpdateType() === 'install') {
this.update(startedByUser);
} else if (
SemVer.compareVersions(UpdateModel.lastVersion, RuntimeInfo.version) > 0
) {
UpdateModel.set({ updateStatus: 'found' });
}
},
error: (e) => {
logger.error('Update check error', e);
UpdateModel.set({
status: 'error',
lastCheckDate: new Date(),
lastCheckError: 'Error checking last version'
});
UpdateModel.save();
this.scheduleNextCheck();
}
});
},
canAutoUpdate() {
const minLauncherVersion = UpdateModel.lastCheckUpdMin;
if (minLauncherVersion) {
const cmp = SemVer.compareVersions(RuntimeInfo.version, minLauncherVersion);
if (cmp < 0) {
UpdateModel.set({ updateStatus: 'ready', updateManual: true });
return false;
}
}
return true;
},
update(startedByUser, successCallback) {
const ver = UpdateModel.lastVersion;
if (!this.enabled) {
logger.info('Updater is disabled');
return;
}
if (SemVer.compareVersions(RuntimeInfo.version, ver) >= 0) {
logger.info('You are using the latest version');
return;
}
UpdateModel.set({ updateStatus: 'downloading', updateError: null });
logger.info('Downloading update', ver);
const updateAssetName = this.getUpdateAssetName(ver);
if (!updateAssetName) {
logger.error('Empty updater asset name for', Launcher.platform(), Launcher.arch());
return;
}
const updateUrlBasePath = Links.UpdateBasePath.replace('{ver}', ver);
const updateAssetUrl = updateUrlBasePath + updateAssetName;
Transport.httpGet({
url: updateAssetUrl,
file: updateAssetName,
cleanupOldFiles: true,
cache: true,
success: (assetFilePath) => {
logger.info('Downloading update signatures');
Transport.httpGet({
url: updateUrlBasePath + 'Verify.sign.sha256',
text: true,
file: updateAssetName + '.sign',
cleanupOldFiles: true,
cache: true,
success: (assetFileSignaturePath) => {
this.verifySignature(assetFilePath, updateAssetName, (err, valid) => {
if (err || !valid) {
UpdateModel.set({
updateStatus: 'error',
updateError: err
? 'Error verifying update signature'
: 'Invalid update signature'
});
Launcher.deleteFile(assetFilePath);
Launcher.deleteFile(assetFileSignaturePath);
return;
}
logger.info('Update is ready', assetFilePath);
UpdateModel.set({ updateStatus: 'ready', updateError: null });
if (!startedByUser) {
Events.emit('update-app');
}
if (typeof successCallback === 'function') {
successCallback();
}
});
},
error(e) {
logger.error('Error downloading update signatures', e);
UpdateModel.set({
updateStatus: 'error',
updateError: 'Error downloading update signatures'
});
}
});
},
error(e) {
logger.error('Error downloading update', e);
UpdateModel.set({
updateStatus: 'error',
updateError: 'Error downloading update'
});
}
});
},
verifySignature(assetFilePath, assetName, callback) {
logger.info('Verifying update signature', assetName);
const fs = Launcher.req('fs');
const signaturesTxt = fs.readFileSync(assetFilePath + '.sign', 'utf8');
const assetSignatureLine = signaturesTxt
.split('\n')
.find((line) => line.endsWith(assetName));
if (!assetSignatureLine) {
logger.error('Signature not found for asset', assetName);
callback('Asset signature not found');
return;
}
const signature = kdbxweb.ByteUtils.hexToBytes(assetSignatureLine.split(' ')[0]);
const fileBytes = fs.readFileSync(assetFilePath);
SignatureVerifier.verify(fileBytes, signature)
.catch((e) => {
logger.error('Error verifying signature', e);
callback('Error verifying signature');
})
.then((valid) => {
logger.info(`Update asset signature is ${valid ? 'valid' : 'invalid'}`);
callback(undefined, valid);
});
},
getUpdateAssetName(ver) {
const platform = Launcher.platform();
const arch = Launcher.arch();
switch (platform) {
case 'win32':
switch (arch) {
case 'x64':
return `KeeWeb-${ver}.win.x64.exe`;
case 'ia32':
return `KeeWeb-${ver}.win.ia32.exe`;
case 'arm64':
return `KeeWeb-${ver}.win.arm64.exe`;
}
break;
case 'darwin':
switch (arch) {
case 'x64':
return `KeeWeb-${ver}.mac.x64.dmg`;
case 'arm64':
return `KeeWeb-${ver}.mac.arm64.dmg`;
}
break;
}
return undefined;
},
installAndRestart() {
if (!Launcher) {
return;
}
const updateAssetName = this.getUpdateAssetName(UpdateModel.lastVersion);
const updateFilePath = Transport.cacheFilePath(updateAssetName);
Launcher.requestRestartAndUpdate(updateFilePath);
}
};
export { Updater };
+69
View File
@@ -0,0 +1,69 @@
import { Events } from 'framework/events';
import { Logger } from 'util/logger';
import { NativeModules } from 'comp/launcher/native-modules';
import { AppSettingsModel } from 'models/app-settings-model';
import { Features } from 'util/features';
const logger = new Logger('usb-listener');
const UsbListener = {
supported: Features.isDesktop,
attachedYubiKeys: 0,
init() {
if (!this.supported) {
return;
}
Events.on('native-modules-yubikeys', (e) => {
if (e.numYubiKeys !== this.attachedYubiKeys) {
logger.debug(`YubiKeys changed ${this.attachedYubiKeys} => ${e.numYubiKeys}`);
this.attachedYubiKeys = e.numYubiKeys;
Events.emit('usb-devices-changed');
}
});
AppSettingsModel.on('change:enableUsb', (model, enabled) => {
if (enabled) {
this.start();
} else {
this.stop();
}
});
if (AppSettingsModel.enableUsb) {
this.start();
}
},
start() {
logger.info('Starting USB listener');
if (this.usb) {
this.stop();
}
try {
NativeModules.startUsbListener();
} catch (e) {
logger.error('Error starting USB listener', e);
}
},
stop() {
logger.info('Stopping USB listener');
try {
NativeModules.stopUsbListener();
} catch (e) {
logger.error('Error stopping USB listener', e);
}
if (this.attachedYubiKeys) {
this.attachedYubiKeys = 0;
Events.emit('usb-devices-changed');
}
}
};
export { UsbListener };
+291
View File
@@ -0,0 +1,291 @@
import { Events } from 'framework/events';
import { Launcher } from 'comp/launcher';
import { NativeModules } from 'comp/launcher/native-modules';
import { Logger } from 'util/logger';
import { UsbListener } from 'comp/app/usb-listener';
import { AppSettingsModel } from 'models/app-settings-model';
import { Timeouts } from 'const/timeouts';
import { YubiKeyProductIds, YubiKeyChallengeSize } from 'const/hardware';
import { Locale } from 'util/locale';
const logger = new Logger('yubikey');
const YubiKey = {
ykmanStatus: undefined,
process: null,
aborted: false,
cmd() {
if (this._cmd) {
return this._cmd;
}
const macYkmanPath = '/usr/local/bin/ykman';
if (Launcher.platform() === 'darwin' && Launcher.fileExistsSync(macYkmanPath)) {
this._cmd = macYkmanPath;
} else {
this._cmd = 'ykman';
}
return this._cmd;
},
checkToolStatus() {
if (this.ykmanStatus === 'ok') {
return Promise.resolve(this.ykmanStatus);
}
return new Promise((resolve) => {
this.ykmanStatus = 'checking';
this._cmd = undefined;
Launcher.spawn({
cmd: this.cmd(),
args: ['-v'],
noStdOutLogging: true,
complete: (err, stdout, code) => {
if (err || code !== 0) {
this.ykmanStatus = 'error';
} else {
this.ykmanStatus = 'ok';
}
resolve(this.ykmanStatus);
}
});
});
},
abort() {
logger.info('Aborting');
if (this.process) {
logger.info('Killing the process');
try {
this.process.kill();
} catch {}
}
this.aborted = true;
this.process = null;
},
list(callback) {
NativeModules.getYubiKeys({})
.then((yubiKeys) => {
yubiKeys = yubiKeys.map(({ serial, vid, pid, version, slots }) => {
return {
vid,
pid,
serial,
slots,
fullName: this.getKeyFullName(pid, version, serial)
};
});
callback(null, yubiKeys);
})
.catch(callback);
},
getKeyFullName(pid, version, serial) {
let name = 'YubiKey';
if (YubiKeyProductIds.Gen1.includes(pid)) {
name += ' Gen 1';
} else if (YubiKeyProductIds.NEO.includes(pid)) {
name += ' NEO';
} else if (YubiKeyProductIds.YK4.includes(pid)) {
if (version >= '5.1.0') {
name += ' 5';
}
}
return `${name} ${serial}`;
},
listWithYkman(callback) {
this._listWithYkman(callback, true);
},
_listWithYkman(callback, canRetry) {
if (this.process) {
return callback('Already in progress');
}
this.aborted = false;
logger.info('Listing YubiKeys');
if (!UsbListener.attachedYubiKeys) {
return callback(null, []);
}
this.process = Launcher.spawn({
cmd: this.cmd(),
args: ['list'],
noStdOutLogging: true,
complete: (err, stdout) => {
this.process = null;
if (this.aborted) {
return callback('Aborted');
}
if (err) {
return callback(err);
}
const yubiKeysIncludingEmpty = stdout
.trim()
.split(/\n/g)
.map((line) => {
const fullName = line;
const serial = (line.match(/\d{5,}$/g) || [])[0];
return { fullName, serial };
});
const yubiKeys = yubiKeysIncludingEmpty.filter((s) => s.serial);
if (
yubiKeysIncludingEmpty.length === 1 &&
yubiKeys.length === 0 &&
stdout.startsWith('YubiKey') &&
stdout.includes('CCID') &&
!stdout.includes('Serial')
) {
logger.info('The YubiKey is probably stuck');
if (!AppSettingsModel.yubiKeyStuckWorkaround) {
return callback(Locale.yubiKeyStuckError);
}
if (canRetry) {
return this._repairStuckYubiKey(callback);
}
}
if (!yubiKeys.length) {
return callback('No YubiKeys returned by "ykman list"');
}
callback(null, yubiKeys);
}
});
},
_repairStuckYubiKey(callback) {
logger.info('Repairing a stuck YubiKey');
let openTimeout;
const countYubiKeys = UsbListener.attachedYubiKeys;
const onDevicesChangedDuringRepair = () => {
if (UsbListener.attachedYubiKeys === countYubiKeys) {
logger.info('YubiKey was reconnected');
Events.off('usb-devices-changed', onDevicesChangedDuringRepair);
clearTimeout(openTimeout);
this.aborted = false;
setTimeout(() => {
this._listWithYkman(callback, false);
}, Timeouts.ExternalDeviceAfterReconnect);
}
};
Events.on('usb-devices-changed', onDevicesChangedDuringRepair);
Launcher.spawn({
cmd: this.cmd(),
args: ['config', 'usb', '-e', 'oath', '-f'],
noStdOutLogging: true,
complete: (err) => {
logger.info('Repair complete', err ? 'with error' : 'OK');
if (err) {
Events.off('usb-devices-changed', onDevicesChangedDuringRepair);
return callback(`YubiKey repair error: ${err}`);
}
openTimeout = setTimeout(() => {
Events.off('usb-devices-changed', onDevicesChangedDuringRepair);
}, Timeouts.ExternalDeviceReconnect);
}
});
},
getOtpCodes(serial, callback) {
if (this.process) {
return callback('Already in progress');
}
this.aborted = false;
this.process = Launcher.spawn({
cmd: this.cmd(),
args: ['-d', serial, 'oath', 'accounts', 'code'],
noStdOutLogging: true,
throwOnStdErr: true,
complete: (err, stdout) => {
this.process = null;
if (this.aborted) {
return callback('Aborted');
}
if (err) {
return callback(err);
}
const codes = [];
for (const line of stdout.split('\n')) {
const match = line.match(/^(.*?):(.*?)\s+(.*)$/);
if (!match) {
continue;
}
const [, title, user, code] = match;
const needsTouch = !code.match(/^\d+$/);
codes.push({
title,
user,
needsTouch
});
}
callback(null, codes);
}
});
},
getOtp(serial, entry, callback) {
return Launcher.spawn({
cmd: this.cmd(),
args: ['-d', serial, 'oath', 'accounts', 'code', '--single', entry],
noStdOutLogging: true,
complete: (err, stdout) => {
if (err) {
return callback(err);
}
const otp = stdout.trim();
callback(null, otp);
}
});
},
calculateChalResp(chalResp, challenge, callback) {
const { vid, pid, serial, slot } = chalResp;
const yubiKey = { vid, pid, serial };
challenge = Buffer.from(challenge);
// https://github.com/Yubico/yubikey-personalization-gui/issues/86
// https://github.com/keepassxreboot/keepassxc/blob/develop/src/keys/drivers/YubiKey.cpp#L318
const padLen = YubiKeyChallengeSize - challenge.byteLength;
const paddedChallenge = Buffer.alloc(YubiKeyChallengeSize, padLen);
challenge.copy(paddedChallenge);
NativeModules.yubiKeyChallengeResponse(
yubiKey,
[...paddedChallenge],
slot,
(err, result) => {
if (result) {
result = Buffer.from(result);
}
if (err) {
err.ykError = true;
}
return callback(err, result);
}
);
},
cancelChalResp() {
NativeModules.yubiKeyCancelChallengeResponse();
}
};
export { YubiKey };
-39
View File
@@ -1,39 +0,0 @@
const FeatureDetector = require('../util/feature-detector');
const Storage = require('../storage');
const AuthReceiver = {
receive: function() {
if (!FeatureDetector.isPopup && !FeatureDetector.isStandalone) {
return false;
}
const opener = window.opener || window.parent;
const message = this.urlArgsToMessage(window.location.href);
const hasKeys = Object.keys(message).filter(key => key !== 'config').length > 0;
if (!hasKeys) {
return false;
}
if (FeatureDetector.isStandalone) {
if (sessionStorage.authStorage) {
Storage[sessionStorage.authStorage].handleOAuthReturnMessage(message);
}
return false;
} else {
opener.postMessage(message, window.location.origin);
window.close();
return true;
}
},
urlArgsToMessage: function(url) {
const message = {};
url.split(/[?#&]/g).forEach(part => {
const parts = part.split('=');
if (parts.length === 2) {
message[parts[0]] = parts[1];
}
});
return message;
}
};
module.exports = AuthReceiver;
+74
View File
@@ -0,0 +1,74 @@
import { Events } from 'framework/events';
import { Launcher } from 'comp/launcher';
import { AppSettingsModel } from 'models/app-settings-model';
const CopyPaste = {
simpleCopy: !!(Launcher && Launcher.clipboardSupported),
copy(text) {
if (this.simpleCopy) {
Launcher.setClipboardText(text);
const clipboardSeconds = AppSettingsModel.clipboardSeconds;
if (clipboardSeconds > 0) {
const clearClipboard = () => {
if (Launcher.getClipboardText() === text) {
Launcher.clearClipboardText();
}
};
Events.on('main-window-will-close', clearClipboard);
setTimeout(() => {
clearClipboard();
Events.off('main-window-will-close', clearClipboard);
}, clipboardSeconds * 1000);
}
return { success: true, seconds: clipboardSeconds };
} else {
try {
if (document.execCommand('copy')) {
return { success: true };
}
} catch (e) {}
return false;
}
},
createHiddenInput(text) {
const hiddenInput = $('<input/>')
.val(text)
.attr({ type: 'text', 'class': 'hide-by-pos' })
.appendTo(document.body);
hiddenInput[0].selectionStart = 0;
hiddenInput[0].selectionEnd = text.length;
hiddenInput.focus();
hiddenInput.on({
'copy cut paste'() {
setTimeout(() => hiddenInput.blur(), 0);
},
blur() {
hiddenInput.remove();
}
});
},
copyHtml(html) {
const el = document.createElement('div');
el.style.userSelect = 'auto';
el.style.webkitUserSelect = 'auto';
el.style.mozUserSelect = 'auto';
el.innerHTML = html;
document.body.appendChild(el);
const range = document.createRange();
range.selectNodeContents(el);
const sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
const result = document.execCommand('copy');
el.remove();
return result;
}
};
export { CopyPaste };
@@ -0,0 +1,41 @@
import { Features } from 'util/features';
const FeatureTester = {
test() {
return Promise.resolve()
.then(() => this.checkWebAssembly())
.then(() => this.checkLocalStorage())
.then(() => this.checkWebCrypto());
},
checkWebAssembly() {
try {
const module = new global.WebAssembly.Module(
Uint8Array.of(0x0, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00)
);
return new global.WebAssembly.Instance(module) instanceof global.WebAssembly.Instance;
} catch (e) {
throw 'WebAssembly is not supported';
}
},
checkLocalStorage() {
if (Features.isDesktop) {
return;
}
try {
localStorage.setItem('_test', '1');
localStorage.removeItem('_test');
} catch (e) {
throw 'LocalStorage is not supported';
}
},
checkWebCrypto() {
if (!global.crypto.subtle) {
throw 'WebCrypto is not supported';
}
}
};
export { FeatureTester };
@@ -1,22 +1,22 @@
const Backbone = require('backbone');
const FeatureDetector = require('../util/feature-detector');
const Launcher = require('../comp/launcher');
import { Events } from 'framework/events';
import { Launcher } from 'comp/launcher';
import { Features } from 'util/features';
const FocusDetector = {
init() {
this.isFocused = true;
this.detectsFocusWithEvents = !FeatureDetector.isDesktop && !FeatureDetector.isMobile;
this.detectsFocusWithEvents = !Features.isDesktop && !Features.isMobile;
if (this.detectsFocusWithEvents) {
window.addEventListener('focus', () => {
if (!FocusDetector.isFocused) {
FocusDetector.isFocused = true;
Backbone.trigger('main-window-focus');
Events.emit('main-window-focus');
}
});
window.addEventListener('blur', () => {
if (FocusDetector.isFocused) {
FocusDetector.isFocused = false;
Backbone.trigger('main-window-blur');
Events.emit('main-window-blur');
}
});
}
@@ -33,4 +33,4 @@ const FocusDetector = {
}
};
module.exports = FocusDetector;
export { FocusDetector };
+24
View File
@@ -0,0 +1,24 @@
import { Events } from 'framework/events';
import { AppSettingsModel } from 'models/app-settings-model';
const IdleTracker = {
actionTime: Date.now(),
init() {
setInterval(this.checkIdle.bind(this), 1000 * 60);
},
checkIdle() {
const idleMinutes = (Date.now() - this.actionTime) / 1000 / 60;
const maxIdleMinutes = AppSettingsModel.idleMinutes;
if (maxIdleMinutes && idleMinutes > maxIdleMinutes) {
Events.emit('before-user-idle');
Events.emit('user-idle');
}
},
regUserAction() {
this.actionTime = Date.now();
}
};
Events.on('power-monitor-resume', () => IdleTracker.checkIdle);
export { IdleTracker };
+139
View File
@@ -0,0 +1,139 @@
import { Events } from 'framework/events';
import { IdleTracker } from 'comp/browser/idle-tracker';
import { Keys } from 'const/keys';
import { FocusManager } from 'comp/app/focus-manager';
const shortcutKeyProp = navigator.platform.indexOf('Mac') >= 0 ? 'metaKey' : 'ctrlKey';
class KeyHandler {
SHORTCUT_ACTION = 1;
SHORTCUT_OPT = 2;
SHORTCUT_SHIFT = 4;
shortcuts = {};
init() {
$(document).bind('keypress', this.keypress.bind(this));
$(document).bind('keydown', this.keydown.bind(this));
this.shortcuts[Keys.DOM_VK_A] = [
{
handler: this.handleAKey,
thisArg: this,
shortcut: this.SHORTCUT_ACTION,
modal: true,
noPrevent: true
}
];
}
onKey(key, handler, thisArg, shortcut, modal, noPrevent) {
let keyShortcuts = this.shortcuts[key];
if (!keyShortcuts) {
this.shortcuts[key] = keyShortcuts = [];
}
keyShortcuts.push({
handler,
thisArg,
shortcut,
modal,
noPrevent
});
}
offKey(key, handler, thisArg) {
if (this.shortcuts[key]) {
this.shortcuts[key] = this.shortcuts[key].filter(
(sh) => sh.handler !== handler || sh.thisArg !== thisArg
);
}
}
isActionKey(e) {
return e[shortcutKeyProp];
}
keydown(e) {
IdleTracker.regUserAction();
const code = e.keyCode || e.which;
const keyShortcuts = this.shortcuts[code];
if (keyShortcuts && keyShortcuts.length) {
for (const sh of keyShortcuts) {
if (FocusManager.modal && sh.modal !== FocusManager.modal && sh.modal !== '*') {
e.stopPropagation();
continue;
}
const isActionKey = this.isActionKey(e);
switch (sh.shortcut) {
case this.SHORTCUT_ACTION:
if (!isActionKey) {
continue;
}
break;
case this.SHORTCUT_OPT:
if (!e.altKey) {
continue;
}
break;
case this.SHORTCUT_SHIFT:
if (!e.shiftKey) {
continue;
}
break;
case this.SHORTCUT_ACTION + this.SHORTCUT_OPT:
if (!e.altKey || !isActionKey) {
continue;
}
break;
default:
if (e.metaKey || e.ctrlKey || e.altKey || e.shiftKey) {
continue;
}
break;
}
sh.handler.call(sh.thisArg, e, code);
if (isActionKey && !sh.noPrevent) {
e.preventDefault();
}
if (e.isImmediatePropagationStopped()) {
break;
}
}
}
}
keypress(e) {
if (
!FocusManager.modal &&
e.which !== Keys.DOM_VK_RETURN &&
e.which !== Keys.DOM_VK_ESCAPE &&
e.which !== Keys.DOM_VK_TAB &&
!e.altKey &&
!e.ctrlKey &&
!e.metaKey
) {
Events.emit('keypress', e);
} else if (FocusManager.modal) {
Events.emit('keypress:' + FocusManager.modal, e);
}
}
reg() {
IdleTracker.regUserAction();
}
handleAKey(e) {
if (
e.target.tagName.toLowerCase() === 'input' &&
['password', 'text'].indexOf(e.target.type) >= 0
) {
e.stopImmediatePropagation();
} else {
e.preventDefault();
}
}
}
const instance = new KeyHandler();
export { instance as KeyHandler };
@@ -0,0 +1,73 @@
import { Events } from 'framework/events';
import { Launcher } from 'comp/launcher';
import { Alerts } from 'comp/ui/alerts';
import { Timeouts } from 'const/timeouts';
import { Locale } from 'util/locale';
import { Logger } from 'util/logger';
import { noop } from 'util/fn';
const PopupNotifier = {
logger: null,
init() {
this.logger = new Logger('popup-notifier');
if (Launcher) {
window.open = noop;
} else {
const windowOpen = window.open;
window.open = function (...args) {
const win = windowOpen.apply(window, args);
if (win) {
PopupNotifier.deferCheckClosed(win);
Events.emit('popup-opened', win);
} else {
if (!Alerts.alertDisplayed) {
Alerts.error({
header: Locale.authPopupRequired,
body: Locale.authPopupRequiredBody
});
}
}
return win;
};
}
},
deferCheckClosed(win) {
setTimeout(PopupNotifier.checkClosed.bind(PopupNotifier, win), Timeouts.CheckWindowClosed);
},
checkClosed(win) {
if (win.closed) {
setTimeout(
PopupNotifier.triggerClosed.bind(PopupNotifier, win),
Timeouts.CheckWindowClosed
);
} else {
const loc = PopupNotifier.tryGetLocationSearch(win);
if (loc) {
try {
win.close();
} catch {}
PopupNotifier.triggerClosed(win, loc);
return;
}
PopupNotifier.deferCheckClosed(win);
}
},
tryGetLocationSearch(win) {
try {
if (win.location.host === location.host) {
return win.location.search;
}
} catch {}
},
triggerClosed(window, locationSearch) {
Events.emit('popup-closed', { window, locationSearch });
}
};
export { PopupNotifier };
@@ -1,6 +1,6 @@
const kdbxweb = require('kdbxweb');
import * as kdbxweb from 'kdbxweb';
const SecureInput = function() {
const SecureInput = function () {
this.el = null;
this.minChar = 0x1400 + Math.round(Math.random() * 100);
this.maxLen = 1024;
@@ -9,13 +9,13 @@ const SecureInput = function() {
this.salt = new Uint32Array(0);
};
SecureInput.prototype.setElement = function(el) {
SecureInput.prototype.setElement = function (el) {
this.el = el;
this.el.val(this.pseudoValue);
this.el.on('input', this._input.bind(this));
};
SecureInput.prototype.reset = function() {
SecureInput.prototype.reset = function () {
this.el = null;
this.length = 0;
this.pseudoValue = '';
@@ -28,7 +28,7 @@ SecureInput.prototype.reset = function() {
this.salt = new Uint32Array(0);
};
SecureInput.prototype._input = function() {
SecureInput.prototype._input = function () {
const selStart = this.el[0].selectionStart;
const value = this.el.val();
let newPs = '';
@@ -63,35 +63,39 @@ SecureInput.prototype._input = function() {
this.el[0].selectionEnd = selStart;
};
SecureInput.prototype._getChar = function(ix) {
SecureInput.prototype._getChar = function (ix) {
return String.fromCharCode(this.minChar + ix);
};
SecureInput.prototype._isSpecialChar = function(ch) {
SecureInput.prototype._isSpecialChar = function (ch) {
return ch >= this.minChar && ch <= this.minChar + this.maxLen;
};
Object.defineProperty(SecureInput.prototype, 'value', {
enumerable: true,
get: function() {
get() {
const pseudoValue = this.pseudoValue;
const salt = this.salt;
const len = pseudoValue.length;
let byteLength = 0;
const valueBytes = new Uint8Array(len * 4);
const saltBytes = kdbxweb.Random.getBytes(len * 4);
const saltBytes = kdbxweb.CryptoEngine.random(len * 4);
let ch;
let bytes;
for (let i = 0; i < len; i++) {
ch = String.fromCharCode(pseudoValue.charCodeAt(i) ^ salt[i]);
const pseudoCharCode = pseudoValue.charCodeAt(i);
ch = String.fromCharCode(salt[i] ^ pseudoCharCode);
bytes = kdbxweb.ByteUtils.stringToBytes(ch);
for (let j = 0; j < bytes.length; j++) {
valueBytes[byteLength] = bytes[j] ^ saltBytes[byteLength];
byteLength++;
}
}
return new kdbxweb.ProtectedValue(valueBytes.buffer.slice(0, byteLength), saltBytes.buffer.slice(0, byteLength));
return new kdbxweb.ProtectedValue(
valueBytes.buffer.slice(0, byteLength),
saltBytes.buffer.slice(0, byteLength)
);
}
});
module.exports = SecureInput;
export { SecureInput };
+19
View File
@@ -0,0 +1,19 @@
import { Events } from 'framework/events';
const ThemeWatcher = {
dark: false,
init() {
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
if (mediaQuery && mediaQuery.addEventListener) {
mediaQuery.addEventListener('change', (e) => {
const dark = e.matches;
this.dark = dark;
Events.emit('dark-mode-changed', { dark });
});
}
this.dark = !!mediaQuery.matches;
}
};
export { ThemeWatcher };
+118
View File
@@ -0,0 +1,118 @@
import { Launcher } from 'comp/launcher';
import { Logger } from 'util/logger';
import { noop } from 'util/fn';
import { StringFormat } from 'util/formatting/string-format';
const logger = new Logger('transport');
const Transport = {
cacheFilePath(fileName) {
return Launcher.getTempPath(fileName);
},
httpGet(config) {
let tmpFile;
const fs = Launcher.req('fs');
if (config.file) {
const baseTempPath = Launcher.getTempPath();
if (config.cleanupOldFiles) {
const allFiles = fs.readdirSync(baseTempPath);
for (const file of allFiles) {
if (
file !== config.file &&
StringFormat.replaceVersion(file, '0') ===
StringFormat.replaceVersion(config.file, '0')
) {
fs.unlinkSync(Launcher.joinPath(baseTempPath, file));
}
}
}
tmpFile = Launcher.joinPath(baseTempPath, config.file);
if (fs.existsSync(tmpFile)) {
try {
if (config.cache && fs.statSync(tmpFile).size > 0) {
logger.info('File already downloaded ' + config.url);
return config.success(tmpFile);
} else {
fs.unlinkSync(tmpFile);
}
} catch (e) {
fs.unlink(tmpFile, noop);
}
}
}
const proto = config.url.split(':')[0];
logger.info('GET ' + config.url);
const opts = Launcher.req('url').parse(config.url);
opts.headers = { 'User-Agent': navigator.userAgent };
Launcher.resolveProxy(config.url, (proxy) => {
logger.info(
'Request to ' +
config.url +
' ' +
(proxy ? 'using proxy ' + proxy.host + ':' + proxy.port : 'without proxy')
);
if (proxy) {
opts.headers.Host = opts.host;
opts.host = proxy.host;
opts.port = proxy.port;
opts.path = config.url;
}
Launcher.req(proto)
.get(opts, (res) => {
logger.info('Response from ' + config.url + ': ' + res.statusCode);
if (res.statusCode === 200) {
if (config.file) {
const file = fs.createWriteStream(tmpFile);
res.pipe(file);
file.on('finish', () => {
file.close(() => {
config.success(tmpFile);
});
});
file.on('error', (err) => {
config.error(err);
});
} else {
let data = [];
res.on('data', (chunk) => {
data.push(chunk);
});
res.on('end', () => {
data = window.Buffer.concat(data);
if (config.text || config.json) {
data = data.toString('utf8');
}
if (config.json) {
try {
data = JSON.parse(data);
} catch (e) {
config.error('Error parsing JSON: ' + e.message);
}
}
config.success(data);
});
}
} else if (res.headers.location && [301, 302].indexOf(res.statusCode) >= 0) {
if (config.noRedirect) {
return config.error('Too many redirects');
}
config.url = res.headers.location;
config.noRedirect = true;
Transport.httpGet(config);
} else {
config.error('HTTP status ' + res.statusCode);
}
})
.on('error', (e) => {
logger.error('Cannot GET ' + config.url, e);
if (tmpFile) {
fs.unlink(tmpFile, noop);
}
config.error(e);
});
});
}
};
export { Transport };

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