From f88c9604dc57e8a51d5f4dbc1ab125bf2e039efb Mon Sep 17 00:00:00 2001 From: Bram van den Heuvel Date: Wed, 1 Mar 2023 12:06:01 +0100 Subject: [PATCH] Add rooms to Credentials --- src/Internal/Credentials.elm | 28 ++++++++++-- src/Internal/Room.elm | 70 +++++++++++++++++++++++++++++ src/Internal/Values/Credentials.elm | 46 +++++++++++-------- 3 files changed, 122 insertions(+), 22 deletions(-) create mode 100644 src/Internal/Room.elm diff --git a/src/Internal/Credentials.elm b/src/Internal/Credentials.elm index 1e107ad..a3a1848 100644 --- a/src/Internal/Credentials.elm +++ b/src/Internal/Credentials.elm @@ -1,32 +1,52 @@ module Internal.Credentials exposing (..) + {-| The Credentials type is the keychain that stores all tokens, values, numbers and other types that need to be remembered. This file combines the internal functions with the API endpoints to create a fully functional Credentials keychain. + -} +import Internal.Room as Room import Internal.Values.Credentials as Internal -{-| -You can consider the `Credentials` type as a large ring of keys, + +{-| You can consider the `Credentials` type as a large ring of keys, and Elm will figure out which key to use. If you pass the `Credentials` into any function, then the library will look for the right keys and tokens to get the right information. -} -type alias Credentials = Internal.Credentials +type alias Credentials = + Internal.Credentials + {-| Get a Credentials type based on an unknown access token. This is an easier way to connect to a Matrix homeserver, but your access may end when the access token expires, is revoked or something else happens. + -} fromAccessToken : { homeserver : String, accessToken : String } -> Credentials fromAccessToken = Internal.fromAccessToken -{-| Get a Credentials type using a username and password. -} + +{-| Get a Credentials type using a username and password. +-} fromLoginCredentials : { username : String, password : String, homeserver : String } -> Credentials fromLoginCredentials = Internal.fromLoginCredentials +{-| Get a room based on its id. +-} +getRoomById : String -> Credentials -> Maybe Room.Room +getRoomById roomId credentials = + Internal.getRoomById roomId credentials + |> Maybe.map + (Room.init + { accessToken = Internal.getAccessTokenType credentials + , baseUrl = Internal.getBaseUrl credentials + , versions = Internal.getVersions credentials + } + ) diff --git a/src/Internal/Room.elm b/src/Internal/Room.elm new file mode 100644 index 0000000..a9e51ff --- /dev/null +++ b/src/Internal/Room.elm @@ -0,0 +1,70 @@ +module Internal.Room exposing (..) + +{-| The `Room` type represents a Matrix Room. In here, you will find utilities to ask information about a room. +-} + +import Internal.Api.All as Api +import Internal.Api.PreApi.Objects.Versions as V +import Internal.Tools.Exceptions as X +import Internal.Tools.LoginValues exposing (AccessToken) +import Internal.Values.Room as Internal +import Json.Encode as E +import Task exposing (Task) + + +{-| The Room type. +-} +type Room + = Room + { room : Internal.Room + , accessToken : AccessToken + , baseUrl : String + , versions : Maybe V.Versions + } + + +init : { accessToken : AccessToken, baseUrl : String, versions : Maybe V.Versions } -> Internal.Room -> Room +init { accessToken, baseUrl, versions } room = + Room + { accessToken = accessToken + , baseUrl = baseUrl + , room = room + , versions = versions + } + + +{-| Get the room's id. +-} +roomId : Room -> String +roomId (Room { room }) = + Internal.roomId room + + +sendEvent : Room -> { eventType : String, content : E.Value } -> Task X.Error Api.CredUpdate +sendEvent (Room { room, accessToken, baseUrl, versions }) { eventType, content } = + Api.sendMessageEvent + { accessToken = accessToken + , baseUrl = baseUrl + , content = content + , eventType = eventType + , roomId = Internal.roomId room + , versions = versions + , extraTransactionNoise = "content-value:" + } + + +sendMessage : Room -> String -> Task X.Error Api.CredUpdate +sendMessage (Room { room, accessToken, baseUrl, versions }) text = + Api.sendMessageEvent + { accessToken = accessToken + , baseUrl = baseUrl + , content = + E.object + [ ( "msgtype", E.string "m.text" ) + , ( "body", E.string text ) + ] + , eventType = "m.room.message" + , roomId = Internal.roomId room + , versions = versions + , extraTransactionNoise = "literal-message:" ++ text + } diff --git a/src/Internal/Values/Credentials.elm b/src/Internal/Values/Credentials.elm index 68d0973..12f5e6a 100644 --- a/src/Internal/Values/Credentials.elm +++ b/src/Internal/Values/Credentials.elm @@ -4,33 +4,42 @@ module Internal.Values.Credentials exposing (..) It handles all communication with the homeserver. -} +import Internal.Api.PreApi.Objects.Versions as V import Internal.Tools.Hashdict as Hashdict exposing (Hashdict) +import Internal.Tools.LoginValues as Login exposing (AccessToken(..)) import Internal.Values.Room as Room exposing (Room) type Credentials - = Credentials { access : AccessToken, homeserver : String, rooms : Hashdict Room } + = Credentials { access : AccessToken, baseUrl : String, rooms : Hashdict Room, versions : Maybe V.Versions } -type AccessToken - = AccessToken String - | NoAccess - | UsernameAndPassword { username : String, password : String, accessToken : Maybe String } - - -{-| Get the access token the Credentials type is using, if any. +{-| Get the stringed access token the Credentials type is using, if any. -} getAccessToken : Credentials -> Maybe String -getAccessToken (Credentials { access }) = - case access of - AccessToken s -> - Just s +getAccessToken = + getAccessTokenType >> Login.getToken - NoAccess -> - Nothing - UsernameAndPassword { accessToken } -> - accessToken +{-| Get the access token type that stores the Credentials's ways of getting access. +-} +getAccessTokenType : Credentials -> AccessToken +getAccessTokenType (Credentials { access }) = + access + + +{-| Get the baseUrl that the credentials accesses. +-} +getBaseUrl : Credentials -> String +getBaseUrl (Credentials { baseUrl }) = + baseUrl + + +{-| Get the versions that the homeserver supports. +-} +getVersions : Credentials -> Maybe V.Versions +getVersions (Credentials { versions }) = + versions {-| Internal value to be used as a "default" for credentials settings. @@ -39,8 +48,9 @@ defaultCredentials : String -> Credentials defaultCredentials homeserver = Credentials { access = NoAccess - , homeserver = homeserver + , baseUrl = homeserver , rooms = Hashdict.empty Room.roomId + , versions = Nothing } @@ -59,7 +69,7 @@ fromLoginCredentials : { username : String, password : String, homeserver : Stri fromLoginCredentials { username, password, homeserver } = case defaultCredentials homeserver of Credentials c -> - Credentials { c | access = UsernameAndPassword { username = username, password = password, accessToken = Nothing } } + Credentials { c | access = UsernameAndPassword { username = username, password = password, token = Nothing } } {-| Get a room from the Credentials type by the room's id.