From 72cd732ebf7d5ac2de35b384dce99b93076e56aa Mon Sep 17 00:00:00 2001 From: Ben Gotow Date: Tue, 14 Jun 2016 13:22:38 -0700 Subject: [PATCH] Pgp patch (#2430) * update icons * style commit * Debugs export function The key Export function used to not successfully show items in their directories and also depend on the most recent attachment download location. This commit adds a new savedState attribute just for Keybase keys and also handles the case where that value is null. * Forces delete to populate fs.watch() was acting up and not triggering populates on deletes. Now deleteKey() just triggers a populate. * Re-enables decryption of attachments from Enigmail Decryption of attachments was disabled in the Great Password Popover Refactor of Early June 2016. This commit adds that feature back (and makes some changes to getKeyContents to facilitate that change). --- internal_packages/keybase/README.md | 7 +-- .../keybase/encrypt-composer-button@2x.png | Bin 4626 -> 15446 bytes internal_packages/keybase/key-present@2x.png | Bin 3322 -> 18218 bytes .../keybase/lib/decrypt-button.cjsx | 45 ++++++++------ .../keybase/lib/email-popover.cjsx | 5 +- .../keybase/lib/pgp-key-store.cjsx | 57 ++++++++++-------- .../keybase/stylesheets/main.less | 29 ++++++--- 7 files changed, 86 insertions(+), 57 deletions(-) diff --git a/internal_packages/keybase/README.md b/internal_packages/keybase/README.md index 13ec1f738..546468fd3 100755 --- a/internal_packages/keybase/README.md +++ b/internal_packages/keybase/README.md @@ -2,17 +2,14 @@ TODO: ----- -* decryption error handling -* remove the .asc extension from decrypted downloads * final refactor * tests -* docs - WISHLIST: ----- * message signing -* encrypted attachment handling +* improved decryption error handling +* encrypted file handling * integrate MIT PGP Keyserver search into Keybase searchbar * make the decrypt interface a message body overlay instead of a button in the header * improve search result deduping with keys on file diff --git a/internal_packages/keybase/encrypt-composer-button@2x.png b/internal_packages/keybase/encrypt-composer-button@2x.png index 589a1a9b4cf7f3b3239ff21fd74f15f251bee260..20cead9ac5b51529caa8db846e025f9c0a977cfc 100644 GIT binary patch literal 15446 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 FV1l7w&ieoW diff --git a/internal_packages/keybase/key-present@2x.png b/internal_packages/keybase/key-present@2x.png index f0d6c812fe9ff6db8048338a8e0610f6c03fdf49..8b5c27f035f4ad93a23383f61ff51131f3f98ca6 100644 GIT binary patch literal 18218 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 delta 587 zcmV-R0<`_Ajsf}^u#*at*F-IUB}qgvnWBjv5@qTkdZ-bjma^3tvsM{tl%9I%p<0a6L!~Kuh=?&_%-z<@|K@i6 zcX$5xMqdtp=llDg@AsVZ`<-)AZ6mD$(T_9H_b|G#u-Z?rIwuSAYgg!hZ^TI~;w|=~ zD~InwH6EfBl^BU)6CuvPc1%Wt7Q&&ZWpN7am`Y-xET->tfOs4#a<-@>11*Y2OR)wj za1Nias{{j$_==ur%-|dt$V;+Puoc(Pj3Xf{P>Ey3s-?@*+PAdFQHN0%vH}ZHt1L!* zv}4Ss^k!opNA*wL%%vB9F&DA|i~wq2fCu{@Sy!<>sdyIWLkw(;oqb)i zl$4sPTK7A~)K}Lh6^Hr|14D7d#g{#%XTN}&s#@a*9w!xt!4Ly~gE))7(m1n}apHN` z9}{J%vLxaQxPZRUD!74L`DDI{1T!DP^`zHv?5UMm$~gY4Q^SS^GjlVcm0A}Xn0p(3 zFBF(S9DWpIU>LLi;4=CZl6-MnFpX_E7(KIEqZ=&*AMhIQFpi(aKFMaI1R9DS7n5;^ zR1CT!1Bp>qfSZawN-4LrdT}|gWUmw}Ug%YvMIWAGMt~+SMw`lo`MrwI^+5g1v Z0RS?FoSVR%6(j%v002ovPDHLkV1k~c7OnsQ diff --git a/internal_packages/keybase/lib/decrypt-button.cjsx b/internal_packages/keybase/lib/decrypt-button.cjsx index ffec80509..8f0137acc 100755 --- a/internal_packages/keybase/lib/decrypt-button.cjsx +++ b/internal_packages/keybase/lib/decrypt-button.cjsx @@ -42,6 +42,14 @@ class DecryptMessageButton extends React.Component {originRect: popoverTarget, direction: 'down'} ) + _onClickDecryptAttachments: (event) => + popoverTarget = event.target.getBoundingClientRect() + + Actions.openPopover( + , + {originRect: popoverTarget, direction: 'down'} + ) + _decryptPopoverDone: (passphrase) => {message} = @props for recipient in message.to @@ -51,31 +59,33 @@ class DecryptMessageButton extends React.Component for privateKey in privateKeys PGPKeyStore.getKeyContents(key: privateKey, passphrase: passphrase) - _onDecryptAttachments: => - console.warn("decrypt attachments") - - ### - _decryptAttachments: => - @_onClick() # unlock keys - PGPKeyStore.decryptAttachments(@state.encryptedAttachments) - ### + _decryptAttachmentsPopoverDone: (passphrase) => + {message} = @props + for recipient in message.to + privateKeys = PGPKeyStore.privKeys(address: recipient.email, timed: false) + for privateKey in privateKeys + PGPKeyStore.getKeyContents(key: privateKey, passphrase: passphrase, callback: (identity) => PGPKeyStore.decryptAttachments(identity, @state.encryptedAttachments)) render: => # TODO inform user of errors/etc. instead of failing without showing it if not (@state.wasEncrypted or @state.encryptedAttachments.length > 0) return false + # TODO a message saying "this was decrypted with the key for ___@___.com" + title = if @state.isDecrypted then "Message Decrypted" else "Message Encrypted" + decryptBody = false if !@state.isDecrypted decryptBody = decryptAttachments = false - ### if @state.encryptedAttachments?.length == 1 - decryptAttachments = + decryptAttachments = + title = "Attachment Encrypted" else if @state.encryptedAttachments?.length > 1 - decryptAttachments = - ### + decryptAttachments = + title = "Attachments Encrypted" + if decryptAttachments or decryptBody decryptionInterface = (
@@ -83,14 +93,15 @@ class DecryptMessageButton extends React.Component { decryptAttachments }
) - # TODO a message saying "this was decrypted with the key for ___@___.com" - title = if @state.isDecrypted then "Message Decrypted" else "Message Encrypted" -
-
{ title }
- {decryptionInterface} +
+
+ { title } +
+ { decryptionInterface } +
diff --git a/internal_packages/keybase/lib/email-popover.cjsx b/internal_packages/keybase/lib/email-popover.cjsx index 541f6d2dc..83ed85976 100644 --- a/internal_packages/keybase/lib/email-popover.cjsx +++ b/internal_packages/keybase/lib/email-popover.cjsx @@ -15,15 +15,12 @@ class EmailPopover extends React.Component participants = @state
- - Associate Emails with Key - - +
_onRecipientFieldChange: (contacts) => diff --git a/internal_packages/keybase/lib/pgp-key-store.cjsx b/internal_packages/keybase/lib/pgp-key-store.cjsx index 3a8a109c1..bd98d8a27 100755 --- a/internal_packages/keybase/lib/pgp-key-store.cjsx +++ b/internal_packages/keybase/lib/pgp-key-store.cjsx @@ -7,6 +7,7 @@ pgp = require 'kbpgp' _ = require 'underscore' path = require 'path' fs = require 'fs' +os = require 'os' class PGPKeyStore extends NylasStore @@ -125,20 +126,26 @@ class PGPKeyStore extends NylasStore console.warn err else if km.is_pgp_locked() - if passphrase? - km.unlock_pgp { passphrase: passphrase }, (err) => - if err - console.warn err - else - console.error "No passphrase provided, but key is encrypted." - # NOTE this only allows for one priv key per address - # if it's already there, update, else insert - key.key = km - key.setTimeout() - @getKeybaseData(key) + # private key - check passphrase + passphrase ?= "" + km.unlock_pgp { passphrase: passphrase }, (err) => + if err + # decrypt checks all keys, so DON'T open an error dialog + console.warn err + return + else + key.key = km + key.setTimeout() + if callback? + callback(key) + else + # public key - get keybase data + key.key = km + key.setTimeout() + @getKeybaseData(key) + if callback? + callback(key) @trigger(@) - if callback? - callback() ) getKeybaseData: (identity) => @@ -174,15 +181,18 @@ class PGPKeyStore extends NylasStore exportKey: ({identity, passphrase}) => atIndex = identity.addresses[0].indexOf("@") - shortName = identity.addresses[0].slice(0, atIndex).concat(".asc") - savePath = path.join(NylasEnv.savedState.lastDownloadDirectory, shortName) - @getKeyContents(key: identity, passphrase: passphrase, callback: ( => + suffix = if identity.isPriv then "-private.asc" else ".asc" + shortName = identity.addresses[0].slice(0, atIndex).concat(suffix) + NylasEnv.savedState.lastKeybaseDownloadDirectory ?= os.homedir() + savePath = path.join(NylasEnv.savedState.lastKeybaseDownloadDirectory, shortName) + @getKeyContents(key: identity, passphrase: passphrase, callback: ( (identity) => NylasEnv.showSaveDialog({ title: "Export PGP Key", defaultPath: savePath, }, (keyPath) => if (!keyPath) return + NylasEnv.savedState.lastKeybaseDownloadDirectory = keyPath.slice(0, keyPath.length - shortName.length) if passphrase? identity.key.export_pgp_private {passphrase: passphrase}, (err, pgp_private) => if (err) @@ -190,14 +200,14 @@ class PGPKeyStore extends NylasStore fs.writeFile(keyPath, pgp_private, (err) => if (err) @_displayError(err) - shell.showItemInFolder(keyPath) + shell.showItemInFolder(keyPath) ) else identity.key.export_pgp_public {}, (err, pgp_public) => fs.writeFile(keyPath, pgp_public, (err) => if (err) @_displayError(err) - shell.showItemInFolder(keyPath) + shell.showItemInFolder(keyPath) ) ) ) @@ -212,6 +222,7 @@ class PGPKeyStore extends NylasStore fs.unlink(key.keyPath, (err) => if (err) @_displayError(err) + @_populate() ) addAddressToKey: (profile, address) => @@ -421,14 +432,13 @@ class PGPKeyStore extends NylasStore console.warn "Unable to decrypt message." @_msgStatus.push({"clientId": message.clientId, "time": Date.now(), "message": "Unable to decrypt message."}) - decryptAttachments: (files) => + decryptAttachments: (identity, files) => # fill our keyring with all possible private keys keyring = new pgp.keyring.KeyRing # (the unbox function will use the right one) - for key in @privKeys({timed: true}) - if key.key? - keyring.add_key_manager(key.key) + if identity.key? + keyring.add_key_manager(identity.key) FileDownloadStore._fetchAndSaveAll(files).then((filepaths) -> # open, decrypt, and resave each of the newly-downloaded files in place @@ -460,11 +470,10 @@ class PGPKeyStore extends NylasStore if literalLen == 1 # success! replace old encrypted file with awesome decrypted file + filepath = filepath.slice(0, filepath.length-3).concat("txt") fs.writeFile(filepath, literals[0].toBuffer(), (err) => if err console.warn err - - # TODO mv the file -> remove .asc extension ) else console.warn "Attempt to decrypt attachment failed: #{literalLen} literals found, expected 1." diff --git a/internal_packages/keybase/stylesheets/main.less b/internal_packages/keybase/stylesheets/main.less index 4b698de2d..ca604e929 100755 --- a/internal_packages/keybase/stylesheets/main.less +++ b/internal_packages/keybase/stylesheets/main.less @@ -177,11 +177,6 @@ } .keybase-decrypt { - .decryption-interface { - button { - margin-right: 10px; - } - } div.line-w-label { display: flex; @@ -189,8 +184,24 @@ color: rgba(128, 128, 128, 0.5); } - div.title-text { - padding: 0 10px; + div.decrypt-bar { + padding: 5px; + border: 1.5px solid rgba(128, 128, 128, 0.5); + border-radius: @border-radius-large; + align-items: center; + display: flex; + + .title-text { + flex: 1; + margin: auto 0; + } + + .decryption-interface { + button { + margin-left: 5px; + } + } + } div.border { @@ -317,6 +328,10 @@ margin-bottom: 10px; } + .empty { + text-align: center; + } + .loading { position: absolute; right: 10px;