A music player that connects to your cloud/distributed storage.
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add ability to not use encryption

+118 -116
+11
src/Applications/Brain.elm
··· 134 134 ----------------------------------------- 135 135 -- User layer #2 136 136 ----------------------------------------- 137 + | RemoveEncryptionKey 137 138 | SaveHypaethralDataSlowly (Debouncer.Msg HypaethralBit) 138 139 | SaveHypaethralData HypaethralBit 139 140 ··· 247 248 ----------------------------------------- 248 249 -- User layer #2 249 250 ----------------------------------------- 251 + RemoveEncryptionKey -> 252 + Alien.AuthSecretKey 253 + |> Alien.trigger 254 + |> Brain.Ports.removeCache 255 + |> returnWithModel model 256 + |> andThen saveAllHypaethralData 257 + 250 258 SaveHypaethralDataSlowly debouncerMsg -> 251 259 Return3.wieldNested 252 260 update ··· 541 549 542 550 Alien.RedirectToBlockstackSignIn -> 543 551 Cmd (Brain.Ports.redirectToBlockstackSignIn ()) 552 + 553 + Alien.RemoveEncryptionKey -> 554 + RemoveEncryptionKey 544 555 545 556 Alien.RemoveTracksBySourceId -> 546 557 data
+29 -36
src/Applications/UI.elm
··· 258 258 -- Authentication 259 259 ----------------------------------------- 260 260 | AuthenticationBootFailure String 261 + | MissingSecretKey Json.Decode.Value 261 262 | NotAuthenticated 262 263 | RemoteStorageWebfinger RemoteStorage.Attributes (Result Http.Error String) 263 - | SyncUserData 264 264 ----------------------------------------- 265 265 -- Children 266 266 ----------------------------------------- ··· 389 389 SetIsOnline False -> 390 390 -- The app went offline, cache everything 391 391 -- (if caching is supported). 392 - (case model.authentication of 392 + ( { model | isOnline = False } 393 + , case model.authentication of 393 394 Authentication.Authenticated (Dropbox _) -> 394 - saveAllHypaethralData { sync = True } 395 + Ports.toBrain (Alien.trigger Alien.SyncHypaethralData) 395 396 396 397 Authentication.Authenticated (RemoteStorage _) -> 397 - saveAllHypaethralData { sync = True } 398 + Ports.toBrain (Alien.trigger Alien.SyncHypaethralData) 398 399 399 400 _ -> 400 - identity 401 + Cmd.none 401 402 ) 402 - ( { model | isOnline = False } 403 - , Cmd.none 404 - ) 405 403 406 404 SetIsOnline True -> 407 405 andThen ··· 409 407 -- If we're back online again, sync all the user's data. 410 408 (case model.authentication of 411 409 Authentication.Authenticated (Dropbox _) -> 412 - update SyncUserData 410 + syncHypaethralData 413 411 414 412 Authentication.Authenticated (RemoteStorage _) -> 415 - update SyncUserData 413 + syncHypaethralData 416 414 417 415 _ -> 418 416 return ··· 506 504 model 507 505 |> showNotification (Notifications.error err) 508 506 |> andThen (translateReply LoadDefaultBackdrop) 507 + 508 + MissingSecretKey json -> 509 + "There seems to be existing data that's encrypted, I will need the passphrase (ie. encryption key) to continue." 510 + |> ShowErrorNotification 511 + |> translateReplyWithModel model 512 + |> andThen (translateReply <| Reply.LoadDefaultBackdrop) 513 + |> andThen (translateReply <| Reply.ToggleLoadingScreen Off) 509 514 510 515 NotAuthenticated -> 511 516 -- This is the message we get when the app initially ··· 547 552 |> Notifications.error 548 553 |> showNotificationWithModel model 549 554 550 - SyncUserData -> 551 - "Syncing" 552 - |> Notifications.warning 553 - |> showNotificationWithModel model 554 - |> saveAllHypaethralData { sync = True } 555 - 556 555 ----------------------------------------- 557 556 -- Children 558 557 ----------------------------------------- ··· 674 673 ----------------------------- 675 674 -- Save all the imported data 676 675 ----------------------------- 677 - |> saveAllHypaethralData { sync = False } 676 + |> saveAllHypaethralData 678 677 679 678 ----------------------------------------- 680 679 -- Notifications ··· 861 860 showNotification notification model 862 861 863 862 863 + syncHypaethralData : Model -> Return Model Msg 864 + syncHypaethralData model = 865 + "Syncing" 866 + |> Notifications.warning 867 + |> showNotificationWithModel model 868 + |> addCommand (Ports.toBrain <| Alien.trigger Alien.SyncHypaethralData) 869 + 870 + 864 871 updateTracksModel : (Tracks.Model -> Tracks.Model) -> Model -> Model 865 872 updateTracksModel fn model = 866 873 { model | tracks = fn model.tracks } ··· 1539 1546 |> Demo.tape 1540 1547 |> LoadHypaethralUserData 1541 1548 |> updateWithModel model 1542 - |> saveAllHypaethralData { sync = False } 1549 + |> saveAllHypaethralData 1543 1550 1544 1551 LoadDefaultBackdrop -> 1545 1552 Backdrop.Default ··· 1614 1621 |> Ports.toBrain 1615 1622 |> returnWithModel model 1616 1623 1617 - SaveTracksFromBrain -> 1618 - Alien.SaveTracks 1619 - |> Alien.trigger 1620 - |> Ports.toBrain 1621 - |> returnWithModel model 1622 1624 1623 - 1624 - saveAllHypaethralData : { sync : Bool } -> Return Model Msg -> Return Model Msg 1625 - saveAllHypaethralData { sync } return = 1625 + saveAllHypaethralData : Return Model Msg -> Return Model Msg 1626 + saveAllHypaethralData return = 1626 1627 List.foldl 1627 1628 (\( _, bit ) -> 1628 1629 case bit of ··· 1642 1643 andThen (translateReply SaveSources) 1643 1644 1644 1645 Tracks -> 1645 - if sync then 1646 - andThen (translateReply SaveTracksFromBrain) 1647 - 1648 - else 1649 - andThen (translateReply SaveTracks) 1646 + andThen (translateReply SaveTracks) 1650 1647 ) 1651 1648 return 1652 1649 hypaethralBit.list ··· 1758 1755 LoadHypaethralUserData event.data 1759 1756 1760 1757 Just Alien.MissingSecretKey -> 1761 - event.data 1762 - |> Json.Decode.decodeValue (Json.Decode.field "alienMethodTag" Alien.tagDecoder) 1763 - |> Result.map (\tag -> Authentication.MissingSecretKey tag event.data) 1764 - |> Result.map AuthenticationMsg 1765 - |> Result.withDefault Bypass 1758 + MissingSecretKey event.data 1766 1759 1767 1760 Just Alien.NotAuthenticated -> 1768 1761 NotAuthenticated
+44 -46
src/Applications/UI/Authentication.elm
··· 15 15 import Html.Styled as Html exposing (Html, a, button, em, fromUnstyled, img, span, text) 16 16 import Html.Styled.Attributes as Attributes exposing (attribute, css, href, placeholder, src, style, target, title, value, width) 17 17 import Html.Styled.Events exposing (onClick, onSubmit) 18 + import Html.Styled.Ext exposing (onClickStopPropagation) 18 19 import Http 19 20 import Json.Decode 20 21 import Json.Encode 21 22 import Markdown 22 23 import Material.Icons exposing (Coloring(..)) 23 24 import Material.Icons.Action as Icons 25 + import Material.Icons.Alert as Icons 24 26 import Material.Icons.Av as Icons 25 27 import Material.Icons.Content as Icons 26 28 import Material.Icons.Navigation as Icons ··· 150 152 -- Encryption 151 153 ----------------------------------------- 152 154 | KeepPassphraseInMemory String 155 + | RemoveEncryptionKey Method 153 156 | ShowNewEncryptionKeyScreen Method 154 157 | ShowUpdateEncryptionKeyScreen Method 155 158 | UpdateEncryptionKey Method String ··· 161 164 | PingOtherIpfs String 162 165 | PingOtherIpfsCallback String (Result Http.Error ()) 163 166 ----------------------------------------- 164 - -- Missing secret key 165 - ----------------------------------------- 166 - | MissingSecretKey Alien.Tag Json.Decode.Value 167 - ----------------------------------------- 168 167 -- More Input 169 168 ----------------------------------------- 170 169 | AskForInput Method Question ··· 228 227 ) 229 228 230 229 SignIn method -> 231 - ( Unauthenticated 230 + ( model 232 231 -- 233 232 , [ ( "method", encodeMethod method ) 234 233 , ( "passphrase", Json.Encode.null ) ··· 247 246 (return model) 248 247 249 248 else 250 - ( Unauthenticated 249 + ( model 251 250 -- 252 251 , [ ( "method", encodeMethod method ) 253 252 , ( "passphrase", Json.Encode.string <| hashPassphrase passphrase ) ··· 279 278 _ -> 280 279 return model 281 280 281 + RemoveEncryptionKey method -> 282 + Alien.RemoveEncryptionKey 283 + |> Alien.trigger 284 + |> Ports.toBrain 285 + |> returnCommandWithModel (Authenticated method) 286 + |> addReply ForceTracksRerender 287 + |> addReply (ShowSuccessNotification "Saving data without encryption ...") 288 + 282 289 ShowNewEncryptionKeyScreen method -> 283 290 return (NewEncryptionKeyScreen method Nothing) 284 291 ··· 292 299 (return model) 293 300 294 301 else 295 - ( Authenticated method 296 - , passphrase 302 + passphrase 297 303 |> hashPassphrase 298 304 |> Json.Encode.string 299 305 |> Alien.broadcast Alien.UpdateEncryptionKey 300 306 |> Ports.toBrain 301 - , [ ForceTracksRerender ] 302 - ) 307 + |> returnCommandWithModel (Authenticated method) 308 + |> addReply ForceTracksRerender 309 + |> addReply (ShowSuccessNotification "Encrypting data with new passphrase ...") 303 310 304 311 ----------------------------------------- 305 312 -- IPFS ··· 352 359 |> returnReplyWithModel model 353 360 354 361 ----------------------------------------- 355 - -- Missing secret key 356 - ----------------------------------------- 357 - MissingSecretKey Alien.AuthAnonymous data -> 358 - returnRepliesWithModel 359 - (NewEncryptionKeyScreen Local Nothing) 360 - [ LoadDefaultBackdrop 361 - , ShowStickySuccessNotification """ 362 - Thanks for upgrading from Diffuse V1! 363 - 364 - In this newer version all your __data is encrypted__, for this we'll need a __passphrase__. 365 - """ 366 - , ToggleLoadingScreen Off 367 - ] 368 - 369 - MissingSecretKey _ data -> 370 - data 371 - |> Json.Decode.decodeValue (Json.Decode.field "fallbackError" Json.Decode.string) 372 - |> Result.withDefault "I seem to be missing your encrypted passphrase, please reauthenticate." 373 - |> ShowErrorNotification 374 - |> returnReplyWithModel model 375 - |> addReply LoadDefaultBackdrop 376 - 377 - ----------------------------------------- 378 362 -- More Input 379 363 ----------------------------------------- 380 364 AskForInput method opts -> ··· 598 582 InputScreen method opts -> 599 583 inputScreen opts 600 584 601 - NewEncryptionKeyScreen method Nothing -> 602 - encryptionKeyScreen (SignInWithPassphrase method "") 603 - 604 - NewEncryptionKeyScreen method (Just passphrase) -> 605 - encryptionKeyScreen (SignInWithPassphrase method passphrase) 585 + NewEncryptionKeyScreen method pass -> 586 + encryptionKeyScreen 587 + { withEncryption = SignInWithPassphrase method (Maybe.withDefault "" pass) 588 + , withoutEncryption = SignIn method 589 + } 606 590 607 - UpdateEncryptionKeyScreen method Nothing -> 608 - encryptionKeyScreen (UpdateEncryptionKey method "") 609 - 610 - UpdateEncryptionKeyScreen method (Just passphrase) -> 611 - encryptionKeyScreen (UpdateEncryptionKey method passphrase) 591 + UpdateEncryptionKeyScreen method pass -> 592 + encryptionKeyScreen 593 + { withEncryption = UpdateEncryptionKey method (Maybe.withDefault "" pass) 594 + , withoutEncryption = RemoveEncryptionKey method 595 + } 612 596 613 597 Unauthenticated -> 614 598 choicesScreen ··· 832 816 -- ENCRYPTION KEY 833 817 834 818 835 - encryptionKeyScreen : Msg -> Html Msg 836 - encryptionKeyScreen msg = 819 + encryptionKeyScreen : { withEncryption : Msg, withoutEncryption : Msg } -> Html Msg 820 + encryptionKeyScreen { withEncryption, withoutEncryption } = 837 821 slab 838 822 Html.form 839 - [ onSubmit msg ] 823 + [ onSubmit withEncryption ] 840 824 [ T.flex 841 825 , T.flex_column 842 826 ] ··· 856 840 Filled 857 841 Bypass 858 842 (text "Continue") 843 + , brick 844 + [ onClickStopPropagation withoutEncryption ] 845 + [ T.f7 846 + , T.flex 847 + , T.items_center 848 + , T.justify_center 849 + , T.lh_title 850 + , T.mt3 851 + , T.pointer 852 + , T.white_50 853 + ] 854 + [ inline [ T.dib, C.lh_0, T.mr2 ] [ fromUnstyled (Icons.warning 13 Inherit) ] 855 + , text "Continue without encryption" 856 + ] 859 857 ] 860 858 861 859
+1 -1
src/Applications/UI/Notifications.elm
··· 70 70 else 71 71 Task.perform 72 72 (\_ -> DismissNotification { id = Notifications.id notification }) 73 - (Process.sleep 5000) 73 + (Process.sleep 7500) 74 74 ) 75 75 76 76
-1
src/Applications/UI/Reply.elm
··· 120 120 | SaveSettings 121 121 | SaveSources 122 122 | SaveTracks 123 - | SaveTracksFromBrain
+21 -10
src/Javascript/Workers/Brain/user.js
··· 146 146 }) 147 147 .then(r => r.ok ? r.text() : r.json()) 148 148 .then(r => r.error ? null : r) 149 - .then(decryptWithSecretKey) 149 + .then(decryptIfNeeded) 150 150 151 151 dataPromise 152 152 .then( sendJsonData(event) ) ··· 196 196 fetch(apiOrigin + "/api/v0/files/read?arg=" + path) 197 197 .then(r => r.ok ? r.text() : r.json()) 198 198 .then(r => r.Code === 0 ? null : r) 199 - .then(decryptWithSecretKey) 199 + .then(decryptIfNeeded) 200 200 .then( sendJsonData(event) ) 201 201 .catch( reportError(event) ) 202 202 }) ··· 303 303 : remoteStorage(event) 304 304 .then(_ => rsClient.getFile(event.data.file)) 305 305 .then(r => r.data) 306 - .then(decryptWithSecretKey) 306 + .then(decryptIfNeeded) 307 307 308 308 dataPromise 309 309 .then( sendJsonData(event) ) 310 - .then( reportError(event) ) 310 + .catch( reportError(event) ) 311 311 }) 312 312 313 313 ··· 353 353 .then(f => f ? Textile.readFile(apiOrigin, f) : null) 354 354 355 355 .then( sendJsonData(event) ) 356 - .then( reportError(event) ) 356 + .catch( reportError(event) ) 357 357 }) 358 358 359 359 ··· 379 379 // 🛠 380 380 381 381 382 - function decryptWithSecretKey(encryptedData) { 383 - return encryptedData 384 - ? getSecretKey().then(secretKey => decrypt(secretKey, encryptedData)) 385 - : null 382 + function decryptIfNeeded(data) { 383 + if (typeof data !== "string") { 384 + return Promise.resolve(data) 385 + 386 + } else if (data.startsWith("{") || data.startsWith("[")) { 387 + return Promise.resolve(data) 388 + 389 + } else { 390 + return data 391 + ? getSecretKey().then(secretKey => decrypt(secretKey, data)) 392 + : Promise.resolve(null) 393 + 394 + } 386 395 } 387 396 388 397 389 398 function encryptWithSecretKey(unencryptedData) { 390 399 return unencryptedData 391 - ? getSecretKey().then(secretKey => encrypt(secretKey, unencryptedData)) 400 + ? getSecretKey() 401 + .then(secretKey => encrypt(secretKey, unencryptedData)) 402 + .catch(_ => unencryptedData) 392 403 : null 393 404 } 394 405
+7 -13
src/Javascript/Workers/brain.js
··· 91 91 92 92 93 93 function fromCache(key) { 94 - if (isAuthMethodService(key)) { 95 - return getFromIndex({ key: key }) 96 - .then(r => getSecretKey().then(s => [r, s])) 97 - .then(([r, s]) => typeof r === "string" ? decrypt(s, r) : r) 98 - .then(d => typeof d === "string" ? JSON.parse(d) : d) 99 - .then(a => a === undefined ? null : a) 100 - 101 - } else { 102 - return getFromIndex({ key: key }) 103 - 104 - } 94 + return isAuthMethodService(key) 95 + ? getFromIndex({ key: key }) 96 + .then(decryptIfNeeded) 97 + .then(d => typeof d === "string" ? JSON.parse(d) : d) 98 + .then(a => a === undefined ? null : a) 99 + : getFromIndex({ key: key }) 105 100 } 106 101 107 102 ··· 109 104 if (isAuthMethodService(key)) { 110 105 const json = JSON.stringify(data) 111 106 112 - return getSecretKey() 113 - .then(secretKey => encrypt(secretKey, json)) 107 + return encryptWithSecretKey(json) 114 108 .then(encryptedData => setInIndex({ key: key, data: encryptedData })) 115 109 116 110 } else {
-9
src/Javascript/crypto.js
··· 60 60 61 61 62 62 function decrypt(key, string) { 63 - if (typeof string !== "string") { 64 - throw("Cannot decrypt a non-string value!") 65 - } 66 - 67 - if (string.trimStart().startsWith("{")) { 68 - // {!} Already decrypted 69 - return string 70 - } 71 - 72 63 const iv_b64 = string.substring(0, 16) 73 64 const buf_b64 = string.substring(16) 74 65
+4
src/Library/Alien.elm
··· 41 41 | ImportLegacyData 42 42 | ProcessSources 43 43 | RedirectToBlockstackSignIn 44 + | RemoveEncryptionKey 44 45 | RemoveTracksBySourceId 45 46 | RemoveTracksFromCache 46 47 | SaveEnclosedUserData ··· 54 55 | SignOut 55 56 | StopProcessing 56 57 | StoreTracksInCache 58 + | SyncHypaethralData 57 59 | ToCache 58 60 | UpdateEncryptionKey 59 61 ----------------------------------------- ··· 93 95 , ( "IMPORT_LEGACY_DATA", ImportLegacyData ) 94 96 , ( "PROCESS_SOURCES", ProcessSources ) 95 97 , ( "REDIRECT_TO_BLOCKSTACK_SIGN_IN", RedirectToBlockstackSignIn ) 98 + , ( "REMOVE_ENCRYPTION_KEY", RemoveEncryptionKey ) 96 99 , ( "REMOVE_TRACKS_BY_SOURCE_ID", RemoveTracksBySourceId ) 97 100 , ( "REMOVE_TRACKS_FROM_CACHE", RemoveTracksFromCache ) 98 101 , ( "SAVE_ENCLOSED_USER_DATA", SaveEnclosedUserData ) ··· 106 109 , ( "SIGN_OUT", SignOut ) 107 110 , ( "STOP_PROCESSING", StopProcessing ) 108 111 , ( "STORE_TRACKS_IN_CACHE", StoreTracksInCache ) 112 + , ( "SYNC_HYPAETHRAL_DATA", SyncHypaethralData ) 109 113 , ( "TO_CACHE", ToCache ) 110 114 , ( "UPDATE_ENCRYPTION_KEY", UpdateEncryptionKey ) 111 115
+1
src/Library/User/Layer.elm
··· 15 15 16 16 -} 17 17 18 + import Alien 18 19 import Dict exposing (Dict) 19 20 import Enum exposing (Enum) 20 21 import Equalizer