Add automated login

pull/1/head
Bram van den Heuvel 2023-03-05 22:43:01 +01:00
parent 9dec58b3d4
commit 692a42bdf8
4 changed files with 210 additions and 5 deletions

View File

@ -8,11 +8,13 @@ that the credentials type needs to know about before it can make a request.
-}
import Internal.Api.PreApi.Objects.Login as L
import Internal.Api.PreApi.Objects.Versions as V
import Internal.Api.Request as R
import Internal.Tools.Exceptions as X
import Internal.Tools.LoginValues exposing (AccessToken(..))
import Internal.Tools.ValueGetter exposing (ValueGetter)
import Json.Encode as E
import Task
import Time
@ -30,10 +32,33 @@ accessToken baseUrl t =
UsernameAndPassword { token } ->
token
, getValue =
"Automated login yet needs to be implemented."
|> X.NotSupportedYet
|> X.SDKException
|> Task.fail
case t of
UsernameAndPassword { username, password } ->
R.rawApiCall
{ headers = R.NoHeaders
, method = "POST"
, baseUrl = baseUrl
, path = "/_matrix/client/v3/login"
, pathParams = []
, queryParams = []
, bodyParams =
[ [ ( "type", E.string "m.id.user" )
, ( "user", E.string username )
]
|> E.object
|> R.RequiredValue "identifier"
, R.RequiredString "password" password
, R.RequiredString "type" "m.login.password"
]
, timeout = Nothing
, decoder = \_ -> L.loggedInResponseDecoder
}
|> Task.map .accessToken
_ ->
X.NoAccessToken
|> X.SDKException
|> Task.fail
}

View File

@ -0,0 +1,135 @@
module Internal.Api.PreApi.Objects.Login exposing
( DiscoveryInformation
, HomeserverInformation
, IdentityServerInformation
, LoggedInResponse
, discoveryInformationDecoder
, encodeDiscoveryInformation
, encodeHomeserverInformation
, encodeIdentityServerInformation
, encodeLoggedInResponse
, homeserverInformationDecoder
, identityServerInformationDecoder
, loggedInResponseDecoder
)
{-| Automatically generated 'Login'
Last generated at Unix time 1677859025
-}
import Internal.Tools.DecodeExtra exposing (opField)
import Internal.Tools.EncodeExtra exposing (maybeObject)
import Json.Decode as D
import Json.Encode as E
{-| Information that overwrites the credential's base url and more.
-}
type alias DiscoveryInformation =
{ mHomeserver : HomeserverInformation
, mIdentityServer : Maybe IdentityServerInformation
}
encodeDiscoveryInformation : DiscoveryInformation -> E.Value
encodeDiscoveryInformation data =
maybeObject
[ ( "m.homeserver", Just <| encodeHomeserverInformation data.mHomeserver )
, ( "m.identity_server", Maybe.map encodeIdentityServerInformation data.mIdentityServer )
]
discoveryInformationDecoder : D.Decoder DiscoveryInformation
discoveryInformationDecoder =
D.map2
(\a b ->
{ mHomeserver = a, mIdentityServer = b }
)
(D.field "m.homeserver" homeserverInformationDecoder)
(opField "m.identity_server" identityServerInformationDecoder)
{-| Used by clients to discover homeserver information.
-}
type alias HomeserverInformation =
{ baseUrl : String
}
encodeHomeserverInformation : HomeserverInformation -> E.Value
encodeHomeserverInformation data =
maybeObject
[ ( "base_url", Just <| E.string data.baseUrl )
]
homeserverInformationDecoder : D.Decoder HomeserverInformation
homeserverInformationDecoder =
D.map
(\a ->
{ baseUrl = a }
)
(D.field "base_url" D.string)
{-| Used by clients to discover identity server information.
-}
type alias IdentityServerInformation =
{ baseUrl : String
}
encodeIdentityServerInformation : IdentityServerInformation -> E.Value
encodeIdentityServerInformation data =
maybeObject
[ ( "base_url", Just <| E.string data.baseUrl )
]
identityServerInformationDecoder : D.Decoder IdentityServerInformation
identityServerInformationDecoder =
D.map
(\a ->
{ baseUrl = a }
)
(D.field "base_url" D.string)
{-| Confirmation that the user has successfully logged in.
-}
type alias LoggedInResponse =
{ accessToken : String
, deviceId : String
, expiresInMs : Maybe Int
, refreshToken : Maybe String
, userId : String
, wellKnown : Maybe DiscoveryInformation
}
encodeLoggedInResponse : LoggedInResponse -> E.Value
encodeLoggedInResponse data =
maybeObject
[ ( "access_token", Just <| E.string data.accessToken )
, ( "device_id", Just <| E.string data.deviceId )
, ( "expires_in_ms", Maybe.map E.int data.expiresInMs )
, ( "refresh_token", Maybe.map E.string data.refreshToken )
, ( "user_id", Just <| E.string data.userId )
, ( "well_known", Maybe.map encodeDiscoveryInformation data.wellKnown )
]
loggedInResponseDecoder : D.Decoder LoggedInResponse
loggedInResponseDecoder =
D.map6
(\a b c d e f ->
{ accessToken = a, deviceId = b, expiresInMs = c, refreshToken = d, userId = e, wellKnown = f }
)
(D.field "access_token" D.string)
(D.field "device_id" D.string)
(opField "expires_in_ms" D.int)
(opField "refresh_token" D.string)
(D.field "user_id" D.string)
(opField "well_known" discoveryInformationDecoder)

View File

@ -0,0 +1,45 @@
version: V_1
name: Login
objects:
LoggedInResponse:
description: Confirmation that the user has successfully logged in.
fields:
access_token:
type: string
required: true
device_id:
type: string
required: true
expires_in_ms:
type: int
required: false
refresh_token:
type: string
required: false
user_id:
type: string
required: true
well_known:
type: DiscoveryInformation
required: false
DiscoveryInformation:
description: Information that overwrites the credential's base url and more.
fields:
m.homeserver:
type: HomeserverInformation
required: true
m.identity_server:
type: IdentityServerInformation
required: false
HomeserverInformation:
description: Used by clients to discover homeserver information.
fields:
base_url:
type: string
required: true
IdentityServerInformation:
description: Used by clients to discover identity server information.
fields:
base_url:
type: string
required: true

View File

@ -161,7 +161,7 @@ updateWith credUpdate ((Credentials ({ cred, context } as data)) as credentials)
-- Add new room
Nothing ->
jroom
|> Room.initFromJoinedRoom { nextBatch = output.nextBatch, roomId = roomId }
|> Room.initFromJoinedRoom { nextBatch = output.nextBatch, roomId = roomId }
)
in
cred