Add method to create a Vault

pull/24/head
Bram 2024-05-26 13:12:03 +02:00
parent e6257d8e38
commit 487c872d43
4 changed files with 122 additions and 9 deletions

View File

@ -1,5 +1,6 @@
module Internal.Values.Context exposing
( Context, AccessToken, init, coder, encode, decoder, mostPopularToken
( Context, AccessToken, init, coder, encode, decoder
, mostPopularToken
, APIContext, apiFormat, fromApiFormat
, setAccessToken, getAccessToken
, setBaseUrl, getBaseUrl
@ -16,7 +17,11 @@ the Matrix API.
## Context
@docs Context, AccessToken, init, coder, encode, decoder, mostPopularToken
@docs Context, AccessToken, init, coder, encode, decoder
Some functions are present to influence the general Context type itself.
@docs mostPopularToken
## APIContext
@ -94,6 +99,7 @@ type alias Context =
, password : Maybe String
, refreshToken : Maybe String
, serverName : String
, suggestedAccessToken : Maybe String
, transaction : Maybe String
, username : Maybe String
, versions : Maybe Versions
@ -146,7 +152,7 @@ fromApiFormat (APIContext c) =
-}
coder : Json.Coder Context
coder =
Json.object10
Json.object11
{ name = Text.docs.context.name
, description = Text.docs.context.description
, init = Context
@ -200,6 +206,13 @@ coder =
, coder = Json.string
}
)
(Json.field.optional.value
{ fieldName = "suggestedAccessToken"
, toField = always Nothing -- Do not save
, description = Debug.todo "Needs docs"
, coder = Json.string
}
)
(Json.field.optional.value
{ fieldName = "transaction"
, toField = .transaction
@ -294,6 +307,7 @@ init sn =
, refreshToken = Nothing
, password = Nothing
, serverName = sn
, suggestedAccessToken = Nothing
, transaction = Nothing
, username = Nothing
, versions = Nothing

View File

@ -1,5 +1,5 @@
module Internal.Values.Vault exposing
( Vault
( Vault, init
, VaultUpdate(..), update
, fromRoomId, mapRoom, updateRoom
, getAccountData, setAccountData
@ -12,7 +12,7 @@ can receive from the Matrix API.
## Vault type
@docs Vault
@docs Vault, init
To update the Vault, one uses VaultUpdate types.
@ -106,6 +106,16 @@ getAccountData key vault =
Dict.get key vault.accountData
{-| Initiate a new Vault type.
-}
init : User -> Vault
init user =
{ accountData = Dict.empty
, rooms = Hashdict.empty .roomId
, user = user
}
{-| Update a room, if it exists. If the room isn´t known, this operation is
ignored.
-}

View File

@ -1,6 +1,7 @@
module Matrix exposing
( Vault
, VaultUpdate, update
, sendMessageEvent, fromUserId
)
{-|
@ -18,18 +19,26 @@ support a monolithic public registry. (:
## Vault
@docs Vault
@docs Vault, fromUserId
## Keeping the Vault up-to-date
@docs VaultUpdate, update
## Debugging
@docs sendMessageEvent
-}
import Internal.Api.Main as Api
import Internal.Values.Envelope as Envelope
import Internal.Values.Vault as Internal
import Json.Encode as E
import Types exposing (Vault(..), VaultUpdate(..))
import Internal.Values.User as User
{-| The Vault type stores all relevant information about the Matrix API.
@ -47,6 +56,49 @@ type alias Vault =
type alias VaultUpdate =
Types.VaultUpdate
addAccessToken : String -> Vault -> Vault
addAccessToken token (Vault vault) =
{-| Use a fully-fledged Matrix ID to connect.
case Matrix.fromUserId "@alice:example.org" of
Just vault ->
"We got a vault!"
Nothing ->
"Invalid username"
-}
fromUserId : String -> Maybe Vault
fromUserId =
User.fromString
>> Maybe.map
(\u ->
Envelope.init
{ serverName = User.domain u
, content = Internal.init u
}
)
>> Maybe.map Vault
{-| Send a message event to a room.
This function can be used in a scenario where the user does not want to sync
the client, or is unable to. This function doesn't check whether the given room
exists and the user is able to send a message to, and instead just sends the
request to the Matrix API.
-}
sendMessageEvent : Vault -> { content : E.Value, eventType : String, roomId : String, toMsg : VaultUpdate -> msg, transactionId : String } -> Cmd msg
sendMessageEvent (Vault vault) data =
Api.sendMessageEvent vault
{ content = data.content
, eventType = data.eventType
, roomId = data.roomId
, toMsg = Types.VaultUpdate >> data.toMsg
, transactionId = data.transactionId
}
{-| Using new VaultUpdate information, update the Vault accordingly.
@ -56,6 +108,6 @@ sent a new message? Did someone send us an invite for a new room?
-}
update : VaultUpdate -> Vault -> Vault
update (VaultUpdate vu) (Vault vault) =
vault
|> Envelope.update Internal.update vu
vu.messages
|> List.foldl (Envelope.update Internal.update) vault
|> Vault

View File

@ -1,5 +1,6 @@
module Matrix.Settings exposing
( getDeviceName, setDeviceName
( setAccessToken, removeAccessToken
, getDeviceName, setDeviceName
, getSyncTime, setSyncTime
)
@ -8,6 +9,18 @@ interact with. Usually, you configure these variables only when creating a new
Vault, or when a user explicitly changes one of their preferred settings.
## Access token
The Vault is able to log in on its own, but sometimes you would rather have the
Vault use an access token than log in to get one on its own. For this case, you
can use this option to insert an access token into the Vault.
As long as the access token remains valid, the Vault will use this provided
access token.
@docs setAccessToken, removeAccessToken
## Device name
The default device name that is being communicated with the Matrix API.
@ -43,6 +56,30 @@ import Internal.Values.Envelope as Envelope
import Types exposing (Vault(..))
{-| Insert a suggested access token.
-}
setAccessToken : String -> Vault -> Vault
setAccessToken token (Vault vault) =
vault
|> Envelope.mapContext
(\c -> { c | suggestedAccessToken = Just token })
|> Vault
{-| Remove an access token that has been inserted using the
[setAccessToken](Matrix-Settings#setAccessToken) function.
This should generally not be necessary, but it can be nice security-wise.
-}
removeAccessToken : Vault -> Vault
removeAccessToken (Vault vault) =
vault
|> Envelope.mapContext
(\c -> { c | suggestedAccessToken = Nothing })
|> Vault
{-| Determine the device name.
-}
getDeviceName : Vault -> String