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.

Proper support for RemoteStorage servers

+68 -17
+29 -13
src/Applications/UI.elm
··· 192 192 returnWithModel model (Ports.unstall ()) 193 193 194 194 ----------------------------------------- 195 + -- Authentication 196 + ----------------------------------------- 197 + RemoteStorageWebfinger remoteStorage (Ok oauthOrigin) -> 198 + let 199 + origin = 200 + Common.urlOrigin model.url 201 + in 202 + remoteStorage 203 + |> Authentication.RemoteStorage.oauthAddress 204 + { oauthOrigin = oauthOrigin 205 + , origin = origin 206 + } 207 + |> Nav.load 208 + |> returnWithModel model 209 + 210 + RemoteStorageWebfinger _ (Err _) -> 211 + UI.Notifications.show 212 + (Notifications.error Authentication.RemoteStorage.webfingerError) 213 + model 214 + 215 + ----------------------------------------- 195 216 -- Brain 196 217 ----------------------------------------- 197 218 SignOut -> ··· 379 400 translateReply reply model = 380 401 case reply of 381 402 ExternalAuth (Authentication.RemoteStorage _) input -> 382 - -- TODO: 383 - -- 1. Make request to RemoteStorage.webfingerAddress 384 - -- 2. If proper response -> Valid RemoteStorage 385 - -- If not -> Not a RemoteStorage -> Show notification 386 - -- 3. Extract oauth address from webfinger response 387 - let 388 - origin = 389 - Common.urlOrigin model.url 390 - in 391 403 input 392 404 |> Authentication.RemoteStorage.parseUserAddress 393 - |> Maybe.map (Authentication.RemoteStorage.oauthAddress { origin = origin }) 394 - |> Maybe.map Nav.load 395 - |> Maybe.withDefault Cmd.none 396 - |> returnWithModel model 405 + |> Maybe.map 406 + (Authentication.RemoteStorage.webfingerRequest RemoteStorageWebfinger) 407 + |> Maybe.unwrap 408 + (UI.Notifications.show 409 + (Notifications.error Authentication.RemoteStorage.userAddressError) 410 + model 411 + ) 412 + (returnWithModel model) 397 413 398 414 ExternalAuth _ _ -> 399 415 return model
+6
src/Applications/UI/Core.elm
··· 1 1 module UI.Core exposing (Flags, Model, Msg(..)) 2 2 3 3 import Authentication 4 + import Authentication.RemoteStorage exposing (RemoteStorage) 4 5 import Browser 5 6 import Browser.Navigation as Nav 6 7 import Common exposing (Switch(..)) 7 8 import ContextMenu exposing (ContextMenu) 8 9 import File exposing (File) 10 + import Http 9 11 import Json.Encode as Json 10 12 import Notifications exposing (..) 11 13 import Queue ··· 91 93 | SetAudioIsLoading Bool 92 94 | SetAudioIsPlaying Bool 93 95 | Unstall 96 + ----------------------------------------- 97 + -- Authentication 98 + ----------------------------------------- 99 + | RemoteStorageWebfinger RemoteStorage (Result Http.Error String) 94 100 ----------------------------------------- 95 101 -- Brain 96 102 -----------------------------------------
+33 -4
src/Library/Authentication/RemoteStorage.elm
··· 1 - module Authentication.RemoteStorage exposing (RemoteStorage, oauthAddress, parseUserAddress) 1 + module Authentication.RemoteStorage exposing (RemoteStorage, oauthAddress, parseUserAddress, userAddressError, webfingerAddress, webfingerDecoder, webfingerError, webfingerRequest) 2 2 3 3 import Base64 4 + import Http 5 + import Json.Decode as Decode exposing (Decoder) 4 6 import Url 5 7 6 8 ··· 14 16 } 15 17 16 18 19 + userAddressError = 20 + "Please provide a valid RemoteStorage address, the format is **user@server**." 21 + 22 + 23 + webfingerError = 24 + "Failed to connect to the given RemoteStorage server." 25 + 26 + 17 27 18 28 -- 🔱 19 29 ··· 28 38 Nothing 29 39 30 40 31 - oauthAddress : { origin : String } -> RemoteStorage -> String 32 - oauthAddress { origin } { host, username } = 41 + oauthAddress : { oauthOrigin : String, origin : String } -> RemoteStorage -> String 42 + oauthAddress { oauthOrigin, origin } { host, username } = 33 43 let 34 44 ua = 35 45 (username ++ "@" ++ host) ··· 37 47 |> Url.percentEncode 38 48 in 39 49 String.concat 40 - [ "https://" ++ host ++ "/rs/oauth/" ++ username 50 + [ oauthOrigin 41 51 , "?redirect_uri=" ++ Url.percentEncode (origin ++ "/authenticate/remotestorage/" ++ ua) 42 52 , "&client_id=" ++ Url.percentEncode origin 43 53 , "&scope=" ++ Url.percentEncode "diffuse-v2:rw" ··· 48 58 webfingerAddress : RemoteStorage -> String 49 59 webfingerAddress { host, username } = 50 60 "https://" ++ host ++ "/.well-known/webfinger?resource=acct:" ++ username 61 + 62 + 63 + webfingerDecoder : Decoder String 64 + webfingerDecoder = 65 + Decode.at 66 + [ "links" 67 + , "0" 68 + , "properties" 69 + , "http://tools.ietf.org/html/rfc6749#section-4.2" 70 + ] 71 + Decode.string 72 + 73 + 74 + webfingerRequest : (RemoteStorage -> Result Http.Error String -> msg) -> RemoteStorage -> Cmd msg 75 + webfingerRequest toMsg rs = 76 + Http.get 77 + { url = webfingerAddress rs 78 + , expect = Http.expectJson (toMsg rs) webfingerDecoder 79 + }