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

Configure Feed

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

Add ability to change passphrase/encryption-key and improve reliability

+356 -157
+15 -3
src/Applications/Brain.elm
··· 80 80 , Cmd.batch 81 81 [ Brain.Ports.toUI alienEvent 82 82 83 - -- 83 + -- Sometimes the loading screen is still showing, 84 + -- so we hide it here just in case. 84 85 , case alienEvent.error of 85 86 Just _ -> 86 87 Brain.Ports.toUI (Alien.trigger Alien.HideLoadingScreen) ··· 215 216 translateReply : Reply -> Msg 216 217 translateReply reply = 217 218 case reply of 218 - Chill -> 219 - Bypass 219 + FabricatedNewSecretKey -> 220 + SaveHypaethralData 220 221 221 222 ----------------------------------------- 222 223 -- To UI ··· 344 345 Just Alien.AuthMethod -> 345 346 AuthenticationMsg (Authentication.MethodRetrieved event.data) 346 347 348 + Just Alien.FabricateSecretKey -> 349 + AuthenticationMsg Authentication.SecretKeyFabricated 350 + 347 351 Just Alien.ProcessSources -> 348 352 -- Only proceed to the processing if we got all the necessary data, 349 353 -- otherwise report an error in the UI. ··· 391 395 392 396 Err err -> 393 397 report Alien.ToCache (Json.errorToString err) 398 + 399 + Just Alien.UpdateEncryptionKey -> 400 + case Json.decodeValue Json.string event.data of 401 + Ok passphrase -> 402 + AuthenticationMsg (Authentication.FabricateSecretKey passphrase) 403 + 404 + Err _ -> 405 + Bypass 394 406 395 407 _ -> 396 408 Bypass
+53 -25
src/Applications/Brain/Authentication.elm
··· 24 24 import Brain.Ports as Ports 25 25 import Brain.Reply exposing (Reply(..)) 26 26 import Conditional exposing (..) 27 - import Json.Decode as J 28 - import Json.Encode 27 + import Json.Decode as Decode 28 + import Json.Encode as J 29 29 import Replying exposing (R3D3, do) 30 30 31 31 ··· 61 61 type Msg 62 62 = PerformSignIn J.Value 63 63 | PerformSignOut 64 + -- 0. Secret Key 65 + | FabricateSecretKey String 66 + | SecretKeyFabricated 64 67 -- 1. Method 65 68 | RetrieveMethod 66 69 | MethodRetrieved J.Value ··· 81 84 -- Set & store method, 82 85 -- and retrieve data. 83 86 PerformSignIn json -> 84 - case decodeMethod json of 85 - Just method -> 86 - ( { model | method = Just method, performingSignIn = True } 87 - , do RetrieveHypaethralData 88 - , Nothing 89 - ) 87 + let 88 + decoder = 89 + Decode.map2 90 + (\a b -> { maybeMethod = a, maybePassphrase = b }) 91 + (Decode.field "method" <| Decode.map methodFromString Decode.string) 92 + (Decode.field "passphrase" <| Decode.maybe Decode.string) 93 + in 94 + case Decode.decodeValue decoder json of 95 + Ok { maybeMethod, maybePassphrase } -> 96 + case maybePassphrase of 97 + Just passphrase -> 98 + ( { model | method = maybeMethod, performingSignIn = True } 99 + , do (FabricateSecretKey passphrase) 100 + , Nothing 101 + ) 102 + 103 + Nothing -> 104 + ( { model | method = maybeMethod, performingSignIn = True } 105 + , do RetrieveHypaethralData 106 + , Nothing 107 + ) 90 108 91 - Nothing -> 109 + _ -> 92 110 ( model 93 111 , Cmd.none 94 112 , Nothing ··· 98 116 -- Unset & remove stored method. 99 117 PerformSignOut -> 100 118 ( { model | method = Nothing } 101 - , Alien.AuthMethod 102 - |> Alien.trigger 103 - |> Ports.removeCache 119 + , Cmd.batch 120 + [ Ports.removeCache (Alien.trigger Alien.AuthMethod) 121 + , Ports.removeCache (Alien.trigger Alien.AuthSecretKey) 122 + ] 104 123 , Nothing 105 124 ) 125 + 126 + ----------------------------------------- 127 + -- # 0 128 + ----------------------------------------- 129 + FabricateSecretKey passphrase -> 130 + ( model 131 + , passphrase 132 + |> J.string 133 + |> Alien.broadcast Alien.FabricateSecretKey 134 + |> Ports.fabricateSecretKey 135 + , Nothing 136 + ) 137 + 138 + SecretKeyFabricated -> 139 + if model.performingSignIn then 140 + ( model, do RetrieveHypaethralData, Nothing ) 141 + 142 + else 143 + ( model, Cmd.none, Just [ FabricatedNewSecretKey ] ) 106 144 107 145 ----------------------------------------- 108 146 -- # 1 ··· 209 247 210 248 211 249 212 - -- JSON 213 - 214 - 215 - decodeMethod : J.Value -> Maybe Method 216 - decodeMethod json = 217 - json 218 - |> J.decodeValue J.string 219 - |> Result.toMaybe 220 - |> Maybe.andThen Authentication.methodFromString 221 - 222 - 223 - 224 250 -- TERMINATION 225 251 226 252 ··· 240 266 241 267 NotAuthenticated -> 242 268 Just 243 - [ NudgeUI Alien.HideLoadingScreen ] 269 + [ NudgeUI Alien.NotAuthenticated 270 + , NudgeUI Alien.HideLoadingScreen 271 + ]
+4 -1
src/Applications/Brain/Ports.elm
··· 1 - port module Brain.Ports exposing (fromAlien, receiveSearchResults, receiveTags, removeCache, removeIpfs, requestCache, requestIpfs, requestSearch, requestTags, toCache, toIpfs, toUI, updateSearchIndex) 1 + port module Brain.Ports exposing (fabricateSecretKey, fromAlien, receiveSearchResults, receiveTags, removeCache, removeIpfs, requestCache, requestIpfs, requestSearch, requestTags, toCache, toIpfs, toUI, updateSearchIndex) 2 2 3 3 import Alien 4 4 import Json.Encode as Json ··· 7 7 8 8 9 9 -- 📣 10 + 11 + 12 + port fabricateSecretKey : Alien.Event -> Cmd msg 10 13 11 14 12 15 port removeCache : Alien.Event -> Cmd msg
+1 -1
src/Applications/Brain/Reply.elm
··· 9 9 10 10 11 11 type Reply 12 - = Chill 12 + = FabricatedNewSecretKey 13 13 -- UI 14 14 | GiveUI Alien.Tag Json.Value 15 15 | NudgeUI Alien.Tag
+23 -17
src/Applications/UI.elm
··· 89 89 ----------------------------------------- 90 90 { contextMenu = Nothing 91 91 , currentTime = Time.millisToPosix flags.initialTime 92 - , isAuthenticated = False 93 92 , isLoading = True 94 93 , navKey = key 95 94 , notifications = [] ··· 141 140 |> N5.reducto update translateReply 142 141 143 142 LoadHypaethralUserData json -> 144 - { model | isAuthenticated = True } 143 + model 145 144 |> UserData.importHypaethral json 146 145 |> N5.reducto update translateReply 147 146 ··· 279 278 |> Ports.toBrain 280 279 in 281 280 { model 282 - | isAuthenticated = False 281 + | authentication = Authentication.initialModel 283 282 , sources = Sources.initialModel 284 283 , tracks = Tracks.initialModel 285 284 } 286 - |> update (AuthenticationMsg Authentication.DischargeMethod) 285 + |> update (BackdropMsg Backdrop.Default) 287 286 |> R2.addCmd alienSigningOut 288 287 |> R2.addCmd (Nav.pushUrl model.navKey "/") 289 288 ··· 516 515 517 516 Reply.AddSourceToCollection source -> 518 517 SourcesMsg (Sources.AddToCollection source) 519 - 520 - Reply.Chill -> 521 - Bypass 522 518 523 519 Reply.DismissNotification opts -> 524 520 Core.DismissNotification opts ··· 614 610 Just Alien.AuthMethod -> 615 611 -- My brain told me which auth method we're using, 616 612 -- so we can tell the user in the UI. 617 - AuthenticationMsg (Authentication.ActivateMethod event.data) 613 + case Authentication.decodeMethod event.data of 614 + Just method -> 615 + AuthenticationMsg (Authentication.SignedIn method) 616 + 617 + Nothing -> 618 + Bypass 618 619 619 620 Just Alien.FinishedProcessingSources -> 620 621 SourcesMsg Sources.FinishedProcessing ··· 628 629 Just Alien.LoadHypaethralUserData -> 629 630 LoadHypaethralUserData event.data 630 631 632 + Just Alien.NotAuthenticated -> 633 + -- There's not to do in this case. 634 + -- (ie. the case when we're not authenticated at the start) 635 + BackdropMsg Backdrop.Default 636 + 631 637 Just Alien.RemoveTracksByPath -> 632 638 TracksMsg (Tracks.RemoveByPaths event.data) 633 639 ··· 729 735 ----------------------------------------- 730 736 -- Content 731 737 ----------------------------------------- 732 - , content 733 - (if model.isLoading then 734 - [ loadingAnimation ] 738 + , case ( model.isLoading, model.authentication ) of 739 + ( True, _ ) -> 740 + content [ loadingAnimation ] 735 741 736 - else if model.isAuthenticated then 737 - defaultScreen model 742 + ( False, Authentication.Authenticated _ ) -> 743 + content (defaultScreen model) 738 744 739 - else 740 - [ model.authentication 745 + ( False, _ ) -> 746 + model.authentication 741 747 |> Authentication.view 742 748 |> Html.map AuthenticationMsg 743 - ] 744 - ) 749 + |> List.singleton 750 + |> content 745 751 ] 746 752 747 753
+184 -95
src/Applications/UI/Authentication.elm
··· 1 - module UI.Authentication exposing (Model, Msg(..), initialModel, update, view) 1 + module UI.Authentication exposing (Model(..), Msg(..), extractMethod, initialModel, update, view) 2 2 3 3 import Alien 4 4 import Authentication exposing (Method(..)) ··· 10 10 import Crypto.Hash 11 11 import Css exposing (pct, px, solid, transparent) 12 12 import Html.Styled as Html exposing (Html, a, button, div, em, fromUnstyled, img, span, text) 13 - import Html.Styled.Attributes exposing (attribute, css, href, placeholder, src, style, type_, width) 14 - import Html.Styled.Events exposing (onClick) 13 + import Html.Styled.Attributes exposing (attribute, css, href, placeholder, src, style, type_, value, width) 14 + import Html.Styled.Events exposing (onClick, onSubmit) 15 15 import Json.Decode as Json 16 16 import Json.Encode 17 17 import Material.Icons.Action as Icons 18 - import Replying exposing (R3D3) 18 + import Replying exposing (R3D3, andThen3) 19 19 import Return2 as R2 20 20 import Return3 as R3 21 21 import Svg exposing (Svg) ··· 29 29 -- 🌳 30 30 31 31 32 - type alias Model = 33 - { encryptionKeyInputFor : Maybe Authentication.Method 34 - , methodInUse : Maybe Authentication.Method 35 - } 32 + type Model 33 + = Authenticated Method 34 + | NewEncryptionKeyScreen Method (Maybe String) 35 + | UpdateEncryptionKeyScreen Method (Maybe String) 36 + | Unauthenticated 36 37 37 38 38 39 initialModel : Model 39 40 initialModel = 40 - { encryptionKeyInputFor = Nothing 41 - , methodInUse = Nothing 42 - } 41 + Unauthenticated 42 + 43 + 44 + extractMethod : Model -> Maybe Method 45 + extractMethod model = 46 + case model of 47 + Authenticated method -> 48 + Just method 49 + 50 + NewEncryptionKeyScreen method _ -> 51 + Just method 52 + 53 + UpdateEncryptionKeyScreen method _ -> 54 + Just method 55 + 56 + Unauthenticated -> 57 + Nothing 43 58 44 59 45 60 ··· 48 63 49 64 type Msg 50 65 = Bypass 51 - | SignIn Authentication.Method 52 - ----------------------------------------- 53 - -- Method 54 - ----------------------------------------- 55 - | ActivateMethod Json.Value 56 - | DischargeMethod 57 - | FabricateSecretKey String 58 - ----------------------------------------- 59 - -- Private Key 60 - ----------------------------------------- 61 66 | HideEncryptionKeyScreen 62 - | ShowEncryptionKeyScreen Authentication.Method 67 + | KeepPassphraseInMemory String 68 + | ShowNewEncryptionKeyScreen Method 69 + | ShowUpdateEncryptionKeyScreen Method 70 + | SignIn Method 71 + | SignInWithPassphrase Method String 72 + | SignedIn Method 73 + | UpdateEncryptionKey Method String 63 74 64 75 65 76 update : Msg -> Model -> R3D3 Model Msg Reply ··· 68 79 Bypass -> 69 80 R3.withNothing model 70 81 82 + HideEncryptionKeyScreen -> 83 + case model of 84 + Authenticated method -> 85 + R3.withNothing (Authenticated method) 86 + 87 + NewEncryptionKeyScreen _ _ -> 88 + R3.withNothing Unauthenticated 89 + 90 + UpdateEncryptionKeyScreen method _ -> 91 + R3.withNothing (Authenticated method) 92 + 93 + Unauthenticated -> 94 + R3.withNothing Unauthenticated 95 + 96 + KeepPassphraseInMemory passphrase -> 97 + case model of 98 + NewEncryptionKeyScreen method _ -> 99 + R3.withNothing (NewEncryptionKeyScreen method <| Just passphrase) 100 + 101 + UpdateEncryptionKeyScreen method _ -> 102 + R3.withNothing (UpdateEncryptionKeyScreen method <| Just passphrase) 103 + 104 + _ -> 105 + R3.withNothing model 106 + 107 + ShowNewEncryptionKeyScreen method -> 108 + R3.withNothing (NewEncryptionKeyScreen method Nothing) 109 + 110 + ShowUpdateEncryptionKeyScreen method -> 111 + R3.withNothing (UpdateEncryptionKeyScreen method Nothing) 112 + 71 113 SignIn method -> 72 - ( { model | encryptionKeyInputFor = Nothing } 73 - , method 74 - |> Authentication.methodToString 75 - |> Json.Encode.string 76 - |> Alien.broadcast Alien.SignIn 77 - |> Ports.toBrain 114 + ( Unauthenticated 115 + , signIn method 78 116 , Just [ ToggleLoadingScreen On ] 79 117 ) 80 118 81 - ----------------------------------------- 82 - -- Method 83 - ----------------------------------------- 84 - ActivateMethod encodedMethod -> 85 - R3.withNothing { model | methodInUse = Authentication.decodeMethod encodedMethod } 119 + SignInWithPassphrase method passphrase -> 120 + ( Unauthenticated 121 + , signInWithPassphrase method passphrase 122 + , Just [ ToggleLoadingScreen On ] 123 + ) 86 124 87 - DischargeMethod -> 88 - R3.withNothing { model | methodInUse = Nothing } 125 + SignedIn method -> 126 + R3.withNothing (Authenticated method) 89 127 90 - FabricateSecretKey passphrase -> 91 - [ ( "tag", Json.Encode.string <| Alien.tagToString Alien.AuthSecretKey ) 92 - , ( "data", Json.Encode.string <| Crypto.Hash.sha256 passphrase ) 93 - , ( "error", Json.Encode.null ) 94 - ] 95 - |> Json.Encode.object 96 - |> Alien.broadcast Alien.ToCache 128 + UpdateEncryptionKey method passphrase -> 129 + ( Authenticated method 130 + , passphrase 131 + |> Crypto.Hash.sha256 132 + |> Json.Encode.string 133 + |> Alien.broadcast Alien.UpdateEncryptionKey 97 134 |> Ports.toBrain 98 - |> R2.withModel model 99 - |> R3.withNoReply 135 + , Nothing 136 + ) 137 + 138 + 139 + signIn : Method -> Cmd Msg 140 + signIn method = 141 + [ ( "method", Authentication.encodeMethod method ) 142 + , ( "passphrase", Json.Encode.null ) 143 + ] 144 + |> Json.Encode.object 145 + |> Alien.broadcast Alien.SignIn 146 + |> Ports.toBrain 100 147 101 - ----------------------------------------- 102 - -- Private Key 103 - ----------------------------------------- 104 - HideEncryptionKeyScreen -> 105 - R3.withNothing { model | encryptionKeyInputFor = Nothing } 106 148 107 - ShowEncryptionKeyScreen method -> 108 - R3.withNothing { model | encryptionKeyInputFor = Just method } 149 + signInWithPassphrase : Method -> String -> Cmd Msg 150 + signInWithPassphrase method passphrase = 151 + [ ( "method", Authentication.encodeMethod method ) 152 + , ( "passphrase", Json.Encode.string <| Crypto.Hash.sha256 passphrase ) 153 + ] 154 + |> Json.Encode.object 155 + |> Alien.broadcast Alien.SignIn 156 + |> Ports.toBrain 109 157 110 158 111 159 ··· 133 181 , width 190 134 182 135 183 -- 136 - , case model.encryptionKeyInputFor of 137 - Just _ -> 184 + , case model of 185 + NewEncryptionKeyScreen _ _ -> 138 186 style "cursor" "pointer" 139 187 140 - Nothing -> 188 + UpdateEncryptionKeyScreen _ _ -> 189 + style "cursor" "pointer" 190 + 191 + _ -> 141 192 style "cursor" "default" 142 193 ] 143 194 [] 144 195 145 196 -- Speech bubble 146 197 ---------------- 147 - , case model.encryptionKeyInputFor of 148 - Just _ -> 198 + , case model of 199 + NewEncryptionKeyScreen _ _ -> 149 200 [ text "I need a passphrase" 150 201 , lineBreak 151 202 , text "to encrypt your data." ··· 153 204 |> chunk [] 154 205 |> speechBubble 155 206 156 - Nothing -> 207 + UpdateEncryptionKeyScreen _ _ -> 208 + [ text "I need a new passphrase" 209 + , lineBreak 210 + , text "to encrypt your data." 211 + ] 212 + |> chunk [] 213 + |> speechBubble 214 + 215 + _ -> 157 216 nothing 158 217 ] 159 218 ] ··· 161 220 ----------------------------------------- 162 221 -- Content 163 222 ----------------------------------------- 164 - , case model.encryptionKeyInputFor of 165 - Just method -> 166 - chunk 167 - [ T.flex 168 - , T.flex_column 169 - ] 170 - [ UI.Kit.textArea 171 - [ attribute "autocomplete" "off" 172 - , attribute "autocorrect" "off" 173 - , attribute "spellcheck" "false" 174 - , placeholder "anQLS9Usw24gxUi11IgVBg76z8SCWZgLKkoWIeJ1ClVmBHLRlaiA0CtvONVAMGritbgd3U45cPTxrhFU0WXaOAa8pVt186KyEccfUNyAq97" 175 - , Html.Styled.Events.onInput FabricateSecretKey 176 - ] 177 - , UI.Kit.button 178 - UI.Kit.Normal 179 - (SignIn method) 180 - (text "Continue") 181 - ] 223 + , case model of 224 + NewEncryptionKeyScreen method Nothing -> 225 + encryptionKeyScreen Bypass 226 + 227 + NewEncryptionKeyScreen method (Just passphrase) -> 228 + encryptionKeyScreen (SignInWithPassphrase method passphrase) 229 + 230 + UpdateEncryptionKeyScreen method Nothing -> 231 + encryptionKeyScreen Bypass 232 + 233 + UpdateEncryptionKeyScreen method (Just passphrase) -> 234 + encryptionKeyScreen (UpdateEncryptionKey method passphrase) 235 + 236 + Unauthenticated -> 237 + choicesScreen 182 238 183 - Nothing -> 184 - chunk 185 - [ T.bg_white 186 - , T.br2 187 - , T.ph3 188 - , T.pv2 189 - ] 190 - [ choiceButton 191 - { action = SignIn Authentication.Local 192 - , icon = Icons.lock_open 193 - , isLast = False 194 - , label = "Store data in the browser" 195 - } 196 - , choiceButton 197 - { action = ShowEncryptionKeyScreen Authentication.Ipfs 198 - , icon = Icons.fingerprint 199 - , isLast = True 200 - , label = "Store encrypted data on IPFS" 201 - } 202 - ] 239 + Authenticated _ -> 240 + choicesScreen 203 241 204 242 ----------------------------------------- 205 243 -- Link to about page ··· 224 262 ] 225 263 226 264 265 + 266 + -- CHOICES 267 + 268 + 269 + encryptionKeyScreen : Msg -> Html Msg 270 + encryptionKeyScreen msg = 271 + chunk 272 + [ T.flex 273 + , T.flex_column 274 + ] 275 + [ UI.Kit.textArea 276 + [ attribute "autocomplete" "off" 277 + , attribute "autocorrect" "off" 278 + , attribute "spellcheck" "false" 279 + , placeholder "anQLS9Usw24gxUi11IgVBg76z8SCWZgLKkoWIeJ1ClVmBHLRlaiA0CtvONVAMGritbgd3U45cPTxrhFU0WXaOAa8pVt186KyEccfUNyAq97" 280 + , Html.Styled.Events.onInput KeepPassphraseInMemory 281 + ] 282 + , UI.Kit.button 283 + UI.Kit.Normal 284 + msg 285 + (text "Continue") 286 + ] 287 + 288 + 289 + choicesScreen : Html Msg 290 + choicesScreen = 291 + chunk 292 + [ T.bg_white 293 + , T.br2 294 + , T.ph3 295 + , T.pv2 296 + ] 297 + [ choiceButton 298 + { action = SignIn Authentication.Local 299 + , icon = Icons.lock_open 300 + , isLast = False 301 + , label = "Store data in the browser" 302 + } 303 + , choiceButton 304 + { action = ShowNewEncryptionKeyScreen Authentication.Ipfs 305 + , icon = Icons.fingerprint 306 + , isLast = True 307 + , label = "Store encrypted data on IPFS" 308 + } 309 + ] 310 + 311 + 227 312 choiceButton : 228 313 { action : msg 229 314 , icon : Color -> Int -> Svg msg ··· 254 339 [ fromUnstyled (icon UI.Kit.colors.text 16) ] 255 340 , text label 256 341 ] 342 + 343 + 344 + 345 + -- ENCRYPTION KEY 257 346 258 347 259 348 speechBubble : Html msg -> Html msg
+5
src/Applications/UI/Backdrop.elm
··· 67 67 68 68 type Msg 69 69 = Choose String 70 + | Default 70 71 | Load String 71 72 72 73 ··· 77 78 { model | chosen = Just backdrop } 78 79 |> R2.withNoCmd 79 80 |> R3.withReply [ Reply.SaveSettings ] 81 + 82 + Default -> 83 + { model | chosen = Just default } 84 + |> R3.withNothing 80 85 81 86 Load backdrop -> 82 87 [ backdrop ]
-1
src/Applications/UI/Core.elm
··· 39 39 type alias Model = 40 40 { contextMenu : Maybe (ContextMenu Msg) 41 41 , currentTime : Time.Posix 42 - , isAuthenticated : Bool 43 42 , isLoading : Bool 44 43 , navKey : Nav.Key 45 44 , notifications : List (Notification Msg)
+10 -1
src/Applications/UI/Kit.elm
··· 1 - module UI.Kit exposing (ButtonType(..), button, buttonFocus, buttonLink, buttonWithColor, buttonWithOptions, canister, centeredContent, checkbox, colorKit, colors, defaultFontFamilies, h1, h2, h3, headerFontFamilies, inlineIcon, inputFocus, insulationWidth, intro, label, link, logoBackdrop, navFocus, receptacle, select, textArea, textField, textFocus, vessel) 1 + module UI.Kit exposing (ButtonType(..), button, buttonFocus, buttonLink, buttonWithColor, buttonWithOptions, canister, centeredContent, checkbox, colorKit, colors, defaultFontFamilies, h1, h2, h3, headerFontFamilies, inlineIcon, inputFocus, insulationWidth, intro, label, link, logoBackdrop, navFocus, receptacle, select, textArea, textButton, textField, textFocus, vessel) 2 2 3 3 import Chunky exposing (..) 4 4 import Color ··· 445 445 , T.w_100 446 446 ] 447 447 [] 448 + 449 + 450 + textButton : { label : String, onClick : msg } -> Html msg 451 + textButton params = 452 + slab 453 + Html.button 454 + [ css linkStyles, onClick params.onClick ] 455 + [ T.bg_transparent, T.color_inherit, T.bn, T.lh_title, T.ma0, T.pa0, T.pointer ] 456 + [ Html.text params.label ] 448 457 449 458 450 459 textField : List (Html.Attribute msg) -> Html msg
-1
src/Applications/UI/Reply.elm
··· 18 18 type Reply 19 19 = ActiveQueueItemChanged (Maybe Queue.Item) 20 20 | AddSourceToCollection Source 21 - | Chill 22 21 | DismissNotification { id : Int } 23 22 | FillQueue 24 23 | GoToPage Page
+16 -2
src/Applications/UI/Settings.elm
··· 7 7 import Material.Icons.Action as Icons 8 8 import Material.Icons.Communication as Icons 9 9 import Tachyons.Classes as T 10 + import UI.Authentication 10 11 import UI.Backdrop 11 12 import UI.Core 12 13 import UI.Kit ··· 59 60 , [ text "Changes are saved automatically." 60 61 , lineBreak 61 62 , text "PS. You're storing the data for this application " 62 - , case model.authentication.methodInUse of 63 + , case UI.Authentication.extractMethod model.authentication of 63 64 Just Ipfs -> 64 - text "on IPFS." 65 + inline 66 + [] 67 + [ text "on IPFS." 68 + , lineBreak 69 + , text "If you want to, you can " 70 + , UI.Kit.textButton 71 + { label = "change your passphrase" 72 + , onClick = 73 + Ipfs 74 + |> UI.Authentication.ShowUpdateEncryptionKeyScreen 75 + |> UI.Core.AuthenticationMsg 76 + } 77 + , text "." 78 + ] 65 79 66 80 Just Local -> 67 81 text "in this browser."
+24 -10
src/Javascript/Workers/brain.js
··· 30 30 31 31 32 32 33 + // Authentication 34 + // -------------- 35 + 36 + app.ports.fabricateSecretKey.subscribe(event => { 37 + keyFromPassphrase(event.data) 38 + .then(data => toCache("AUTH_SECRET_KEY", data)) 39 + .then(_ => { 40 + app.ports.fromAlien.send({ 41 + tag: event.tag, 42 + data: null, 43 + error: null 44 + }) 45 + }) 46 + .catch(reportError(event)) 47 + }) 48 + 49 + 50 + 33 51 // Cache 34 52 // ----- 35 53 ··· 53 71 54 72 55 73 app.ports.toCache.subscribe(event => { 56 - const dataPromise = (_ => { 57 - switch (event.tag) { 58 - case "AUTH_SECRET_KEY": return keyFromPassphrase(event.data) 59 - default: return Promise.resolve(event.data) 60 - } 61 - })() 62 - 63 - dataPromise 64 - .then(data => setInIndex({ key: event.tag, data: data })) 65 - .catch(reportError(event)) 74 + toCache(event.tag, event.data).catch(reportError(event)) 66 75 }) 76 + 77 + 78 + function toCache(key, data) { 79 + return setInIndex({ key: key, data: data }) 80 + } 67 81 68 82 69 83
+21
src/Library/Alien.elm
··· 25 25 | AuthIpfs 26 26 | AuthMethod 27 27 | AuthSecretKey 28 + | FabricateSecretKey 28 29 | SearchTracks 29 30 -- from UI 30 31 | ProcessSources ··· 36 37 | SignIn 37 38 | SignOut 38 39 | ToCache 40 + | UpdateEncryptionKey 39 41 -- to UI 40 42 | AddTracks 41 43 | FinishedProcessingSources 42 44 | HideLoadingScreen 43 45 | LoadEnclosedUserData 44 46 | LoadHypaethralUserData 47 + | NotAuthenticated 45 48 | RemoveTracksByPath 46 49 | ReportProcessingError 47 50 | UpdateSourceData ··· 92 95 93 96 AuthSecretKey -> 94 97 "AUTH_SECRET_KEY" 98 + 99 + FabricateSecretKey -> 100 + "FABRICATE_SECRET_KEY" 95 101 96 102 SearchTracks -> 97 103 "SEARCH_TRACKS" ··· 126 132 ToCache -> 127 133 "TO_CACHE" 128 134 135 + UpdateEncryptionKey -> 136 + "UPDATE_ENCRYPTION_KEY" 137 + 129 138 ----------------------------------------- 130 139 -- To UI 131 140 ----------------------------------------- ··· 144 153 LoadHypaethralUserData -> 145 154 "LOAD_HYPAETHRAL_USER_DATA" 146 155 156 + NotAuthenticated -> 157 + "NOT_AUTHENTICATED" 158 + 147 159 RemoveTracksByPath -> 148 160 "REMOVE_TRACKS_BY_PATH" 149 161 ··· 171 183 172 184 "AUTH_SECRET_KEY" -> 173 185 Just AuthSecretKey 186 + 187 + "FABRICATE_SECRET_KEY" -> 188 + Just FabricateSecretKey 174 189 175 190 "SEARCH_TRACKS" -> 176 191 Just SearchTracks ··· 205 220 "TO_CACHE" -> 206 221 Just ToCache 207 222 223 + "UPDATE_ENCRYPTION_KEY" -> 224 + Just UpdateEncryptionKey 225 + 208 226 ----------------------------------------- 209 227 -- UI 210 228 ----------------------------------------- ··· 222 240 223 241 "LOAD_HYPAETHRAL_USER_DATA" -> 224 242 Just LoadHypaethralUserData 243 + 244 + "NOT_AUTHENTICATED" -> 245 + Just NotAuthenticated 225 246 226 247 "REMOVE_TRACKS_BY_PATH" -> 227 248 Just RemoveTracksByPath