A music player that connects to your cloud/distributed storage.
at main 3.0 kB view raw
1module User.Layer.Methods.RemoteStorage exposing (Attributes, oauthAddress, parseUserAddress, userAddressError, webfingerAddress, webfingerDecoder, webfingerError, webfingerRequest) 2 3import Base64 4import Http 5import Json.Decode as Decode exposing (Decoder) 6import Url 7import UrlBase64 8 9 10 11-- 🌳 12 13 14type alias Attributes = 15 { host : String 16 , username : String 17 } 18 19 20userAddressError = 21 "Please provide a valid RemoteStorage address, the format is **user@server**" 22 23 24webfingerError = 25 "**Failed to connect** to the given RemoteStorage server, maybe a typo?" 26 27 28 29-- 🔱 30 31 32parseUserAddress : String -> Maybe Attributes 33parseUserAddress str = 34 case String.split "@" str of 35 [ u, h ] -> 36 Just { host = h, username = u } 37 38 _ -> 39 Nothing 40 41 42oauthAddress : { oauthOrigin : String, origin : String } -> Attributes -> String 43oauthAddress { oauthOrigin, origin } { host, username } = 44 let 45 hostWithoutProtocol = 46 host 47 |> String.split "://" 48 |> List.drop 1 49 |> List.head 50 |> Maybe.withDefault host 51 52 ua = 53 (username ++ "@" ++ hostWithoutProtocol) 54 |> UrlBase64.encode (Base64.encode >> Ok) 55 |> Result.withDefault "BASE64_ENCODING_FAILED" 56 in 57 String.concat 58 [ oauthOrigin 59 , "?redirect_uri=" ++ Url.percentEncode (origin ++ "?action=authenticate/remotestorage/" ++ ua) 60 , "&client_id=" ++ Url.percentEncode origin 61 , "&scope=" ++ Url.percentEncode "diffuse:rw" 62 , "&response_type=token" 63 ] 64 65 66webfingerAddress : Url.Protocol -> Attributes -> String 67webfingerAddress originProtocol { host, username } = 68 let 69 fallbackProtocol = 70 case originProtocol of 71 Url.Http -> 72 "http" 73 74 Url.Https -> 75 "https" 76 77 protocol = 78 if String.contains "://" host then 79 host 80 |> String.split "://" 81 |> List.head 82 |> Maybe.withDefault fallbackProtocol 83 84 else 85 fallbackProtocol 86 87 hostWithoutProtocol = 88 host 89 |> String.split "://" 90 |> List.drop 1 91 |> List.head 92 |> Maybe.withDefault host 93 in 94 protocol ++ "://" ++ hostWithoutProtocol ++ "/.well-known/webfinger?resource=acct:" ++ Url.percentEncode (username ++ "@" ++ hostWithoutProtocol) 95 96 97webfingerDecoder : Decoder String 98webfingerDecoder = 99 Decode.at 100 [ "links" 101 , "0" 102 , "properties" 103 , "http://tools.ietf.org/html/rfc6749#section-4.2" 104 ] 105 Decode.string 106 107 108webfingerRequest : (Attributes -> Result Http.Error String -> msg) -> Url.Protocol -> Attributes -> Cmd msg 109webfingerRequest toMsg originProtocol rs = 110 Http.get 111 { url = webfingerAddress originProtocol rs 112 , expect = Http.expectJson (toMsg rs) webfingerDecoder 113 }