diff --git a/development/build_objects.py b/development/build_objects.py index 8e2333d..48037df 100644 --- a/development/build_objects.py +++ b/development/build_objects.py @@ -219,7 +219,13 @@ def main(in_file, out_file): @property def encoder(self): - if self.required or self.default is not None: + if self.required == 'never': + return 'Nothing' + elif self.required == 'now': + return ( + 'Maybe.map ' + encapsulate(self.field.encoder) + ' data.' + self.elm_name + ) + elif self.required or self.default is not None: return ( 'Just <| ' + self.field.encoder + ' data.' + self.elm_name ) @@ -232,7 +238,11 @@ def main(in_file, out_file): @property def decoder(self): - if self.required: + if self.required == 'never': + return 'D.succeed Nothing' + elif self.required == 'now': + field = f'D.map Just <| D.field "{self.key}"' + elif self.required: field = f'D.field "{self.key}"' elif self.default is None: field = f'opField "{self.key}"' @@ -243,7 +253,9 @@ def main(in_file, out_file): @property def type_definition(self): - if self.required or self.default is not None: + if self.required in ['now', 'never']: + return 'Maybe ' + encapsulate(self.field.type_name) + elif self.required or self.default is not None: return self.field.type_name else: return 'Maybe ' + encapsulate(self.field.type_name) @@ -330,11 +342,11 @@ def main(in_file, out_file): if 'Dict' in content: write("import Dict exposing (Dict)\n") - if 'opField' in content and 'opFieldWithDefault' in content: + if 'opField ' in content and 'opFieldWithDefault ' in content: write("import Internal.Tools.DecodeExtra exposing (opField, opFieldWithDefault)\n") - elif 'opFieldWithDefault' in content: - write("import Internal.Tools.DecodeExtra exposing (opField)\n") - elif 'opField' in content: + elif 'opFieldWithDefault ' in content: + write("import Internal.Tools.DecodeExtra exposing (opFieldWithDefault)\n") + elif 'opField ' in content: write("import Internal.Tools.DecodeExtra exposing (opField)\n") if 'maybeObject' in content: diff --git a/src/Internal/Api/LoginWithUsernameAndPassword/Api.elm b/src/Internal/Api/LoginWithUsernameAndPassword/Api.elm index d4253d2..b98ce25 100644 --- a/src/Internal/Api/LoginWithUsernameAndPassword/Api.elm +++ b/src/Internal/Api/LoginWithUsernameAndPassword/Api.elm @@ -1,6 +1,10 @@ module Internal.Api.LoginWithUsernameAndPassword.Api exposing (..) -import Internal.Api.LoginWithUsernameAndPassword.V1.Login as SO +import Internal.Api.LoginWithUsernameAndPassword.V1.Login as SO1 +import Internal.Api.LoginWithUsernameAndPassword.V2.SpecObjects as SO2 +import Internal.Api.LoginWithUsernameAndPassword.V3.SpecObjects as SO3 +import Internal.Api.LoginWithUsernameAndPassword.V4.SpecObjects as SO4 +import Internal.Api.LoginWithUsernameAndPassword.V5.Login as SO5 import Internal.Api.Request as R import Internal.Tools.Context exposing (Context) import Internal.Tools.Exceptions as X @@ -14,20 +18,138 @@ type alias LoginWithUsernameAndPasswordInputV1 = } +type alias LoginWithUsernameAndPasswordInputV2 = + { deviceId : Maybe String + , initialDeviceDisplayName : Maybe String + , password : String + , username : String + } + + type alias LoginWithUsernameAndPasswordOutputV1 = - SO.LoggedInResponse + SO1.LoggedInResponse + + +type alias LoginWithUsernameAndPasswordOutputV2 = + SO2.LoggedInResponse + + +type alias LoginWithUsernameAndPasswordOutputV3 = + SO3.LoggedInResponse + + +type alias LoginWithUsernameAndPasswordOutputV4 = + SO4.LoggedInResponse + + +type alias LoginWithUsernameAndPasswordOutputV5 = + SO5.LoggedInResponse loginWithUsernameAndPasswordV1 : LoginWithUsernameAndPasswordInputV1 -> Context { a | baseUrl : () } -> Task X.Error LoginWithUsernameAndPasswordOutputV1 loginWithUsernameAndPasswordV1 { username, password } = - R.callApi "POST" "/_matrix/client/v3/login" + R.callApi "POST" "/_matrix/client/r0/login" >> R.withAttributes - [ [ ( "type", E.string "m.id.user" ) + [ R.bodyString "password" password + , R.bodyString "type" "m.login.password" + , R.bodyString "user" username + ] + >> R.toTask SO1.loggedInResponseDecoder + + +loginWithUsernameAndPasswordV2 : LoginWithUsernameAndPasswordInputV2 -> Context { a | baseUrl : () } -> Task X.Error LoginWithUsernameAndPasswordOutputV2 +loginWithUsernameAndPasswordV2 { deviceId, initialDeviceDisplayName, password, username } = + R.callApi "POST" "/_matrix/client/r0/login" + >> R.withAttributes + [ R.bodyString "type" "m.login.password" + , R.bodyString "user" username + , R.bodyString "password" password + , R.bodyOpString "device_id" deviceId + , R.bodyOpString "initial_device_display_name" initialDeviceDisplayName + ] + >> R.toTask SO2.loggedInResponseDecoder + + +loginWithUsernameAndPasswordV3 : LoginWithUsernameAndPasswordInputV2 -> Context { a | baseUrl : () } -> Task X.Error LoginWithUsernameAndPasswordOutputV3 +loginWithUsernameAndPasswordV3 { deviceId, initialDeviceDisplayName, password, username } = + R.callApi "POST" "/_matrix/client/r0/login" + >> R.withAttributes + [ R.bodyString "type" "m.login.password" + , R.bodyString "password" password + , R.bodyOpString "device_id" deviceId + , R.bodyOpString "initial_device_display_name" initialDeviceDisplayName + , [ ( "type", E.string "m.id.user" ) , ( "user", E.string username ) ] |> E.object |> R.bodyValue "identifier" - , R.bodyString "password" password - , R.bodyString "type" "m.login.password" ] - >> R.toTask SO.loggedInResponseDecoder + >> R.toTask SO3.loggedInResponseDecoder + + +loginWithUsernameAndPasswordV4 : LoginWithUsernameAndPasswordInputV2 -> Context { a | baseUrl : () } -> Task X.Error LoginWithUsernameAndPasswordOutputV4 +loginWithUsernameAndPasswordV4 { deviceId, initialDeviceDisplayName, password, username } = + R.callApi "POST" "/_matrix/client/r0/login" + >> R.withAttributes + [ R.bodyString "type" "m.login.password" + , R.bodyString "password" password + , R.bodyOpString "device_id" deviceId + , R.bodyOpString "initial_device_display_name" initialDeviceDisplayName + , [ ( "type", E.string "m.id.user" ) + , ( "user", E.string username ) + ] + |> E.object + |> R.bodyValue "identifier" + ] + >> R.toTask SO4.loggedInResponseDecoder + + +loginWithUsernameAndPasswordV5 : LoginWithUsernameAndPasswordInputV2 -> Context { a | baseUrl : () } -> Task X.Error LoginWithUsernameAndPasswordOutputV4 +loginWithUsernameAndPasswordV5 { deviceId, initialDeviceDisplayName, password, username } = + R.callApi "POST" "/_matrix/client/v3/login" + >> R.withAttributes + [ R.bodyString "type" "m.login.password" + , R.bodyString "password" password + , R.bodyOpString "device_id" deviceId + , R.bodyOpString "initial_device_display_name" initialDeviceDisplayName + , [ ( "type", E.string "m.id.user" ) + , ( "user", E.string username ) + ] + |> E.object + |> R.bodyValue "identifier" + ] + >> R.toTask SO4.loggedInResponseDecoder + + +loginWithUsernameAndPasswordV6 : LoginWithUsernameAndPasswordInputV2 -> Context { a | baseUrl : () } -> Task X.Error LoginWithUsernameAndPasswordOutputV5 +loginWithUsernameAndPasswordV6 { deviceId, initialDeviceDisplayName, password, username } = + R.callApi "POST" "/_matrix/client/v3/login" + >> R.withAttributes + [ R.bodyString "type" "m.login.password" + , R.bodyString "password" password + , R.bodyOpString "device_id" deviceId + , R.bodyOpString "initial_device_display_name" initialDeviceDisplayName + , R.bodyBool "refresh_token" True + , [ ( "type", E.string "m.id.user" ) + , ( "user", E.string username ) + ] + |> E.object + |> R.bodyValue "identifier" + ] + >> R.toTask SO5.loggedInResponseDecoder + + + +-- loginWithUsernameAndPasswordV5 : LoginWithUsernameAndPasswordInputV1 -> Context { a | baseUrl : () } -> Task X.Error LoginWithUsernameAndPasswordOutputV5 +-- loginWithUsernameAndPasswordV5 { username, password } = +-- R.callApi "POST" "/_matrix/client/v3/login" +-- >> R.withAttributes +-- [ [ ( "type", E.string "m.id.user" ) +-- , ( "user", E.string username ) +-- ] +-- |> E.object +-- |> R.bodyValue "identifier" +-- , R.bodyString "password" password +-- , R.bodyString "type" "m.login.password" +-- ] +-- >> R.toTask SO.loggedInResponseDecoder diff --git a/src/Internal/Api/LoginWithUsernameAndPassword/Main.elm b/src/Internal/Api/LoginWithUsernameAndPassword/Main.elm index c05a76d..5378d5d 100644 --- a/src/Internal/Api/LoginWithUsernameAndPassword/Main.elm +++ b/src/Internal/Api/LoginWithUsernameAndPassword/Main.elm @@ -1,6 +1,10 @@ module Internal.Api.LoginWithUsernameAndPassword.Main exposing (..) import Internal.Api.LoginWithUsernameAndPassword.Api as Api +import Internal.Api.LoginWithUsernameAndPassword.V2.Upcast as U2 +import Internal.Api.LoginWithUsernameAndPassword.V3.Upcast as U3 +import Internal.Api.LoginWithUsernameAndPassword.V4.Upcast as U4 +import Internal.Api.LoginWithUsernameAndPassword.V5.Upcast as U5 import Internal.Tools.Context as Context exposing (Context, VB) import Internal.Tools.Exceptions as X import Internal.Tools.VersionControl as VC @@ -11,8 +15,54 @@ loginWithUsernameAndPassword : Context (VB a) -> LoginWithUsernameAndPasswordInp loginWithUsernameAndPassword context input = VC.withBottomLayer { current = Api.loginWithUsernameAndPasswordV1 - , version = "v1.5" + , version = "r0.0.0" } + |> VC.sameForVersion "r0.0.1" + |> VC.sameForVersion "r0.1.0" + |> VC.sameForVersion "r0.2.0" + |> VC.addMiddleLayer + { downcast = \{ username, password } -> { username = username, password = password } + , current = Api.loginWithUsernameAndPasswordV2 + , upcast = + \f c -> + Task.map U2.upcastLoggedInResponse (f c) + , version = "r0.3.0" + } + |> VC.addMiddleLayer + { downcast = identity + , current = Api.loginWithUsernameAndPasswordV3 + , upcast = + \f c -> + Task.map U3.upcastLoggedInResponse (f c) + , version = "r0.4.0" + } + |> VC.addMiddleLayer + { downcast = identity + , current = Api.loginWithUsernameAndPasswordV4 + , upcast = + \f c -> + Task.map U4.upcastLoggedInResponse (f c) + , version = "r0.5.0" + } + |> VC.sameForVersion "r0.6.0" + |> VC.sameForVersion "r0.6.1" + |> VC.addMiddleLayer + { downcast = identity + , current = Api.loginWithUsernameAndPasswordV5 + , upcast = identity + , version = "v1.1" + } + |> VC.sameForVersion "v1.2" + |> VC.addMiddleLayer + { downcast = identity + , current = Api.loginWithUsernameAndPasswordV6 + , upcast = + \f c -> + Task.map U5.upcastLoggedInResponse (f c) + , version = "v1.3" + } + |> VC.sameForVersion "v1.4" + |> VC.sameForVersion "v1.5" |> VC.sameForVersion "v1.6" |> VC.mostRecentFromVersionList (Context.getVersions context) |> Maybe.withDefault (always <| always <| Task.fail X.UnsupportedSpecVersion) @@ -21,8 +71,8 @@ loginWithUsernameAndPassword context input = type alias LoginWithUsernameAndPasswordInput = - Api.LoginWithUsernameAndPasswordInputV1 + Api.LoginWithUsernameAndPasswordInputV2 type alias LoginWithUsernameAndPasswordOutput = - Api.LoginWithUsernameAndPasswordOutputV1 + Api.LoginWithUsernameAndPasswordOutputV5 diff --git a/src/Internal/Api/LoginWithUsernameAndPassword/V1/Login.elm b/src/Internal/Api/LoginWithUsernameAndPassword/V1/Login.elm index f4e33a8..3cb8991 100644 --- a/src/Internal/Api/LoginWithUsernameAndPassword/V1/Login.elm +++ b/src/Internal/Api/LoginWithUsernameAndPassword/V1/Login.elm @@ -1,21 +1,12 @@ module Internal.Api.LoginWithUsernameAndPassword.V1.Login exposing - ( DiscoveryInformation - , HomeserverInformation - , IdentityServerInformation - , LoggedInResponse - , discoveryInformationDecoder - , encodeDiscoveryInformation - , encodeHomeserverInformation - , encodeIdentityServerInformation + ( LoggedInResponse , encodeLoggedInResponse - , homeserverInformationDecoder - , identityServerInformationDecoder , loggedInResponseDecoder ) {-| Automatically generated 'Login' -Last generated at Unix time 1677859025 +Last generated at Unix time 1679075857 -} @@ -25,87 +16,13 @@ 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. +{-| Confirmation that the user successfully logged in. -} type alias LoggedInResponse = { accessToken : String - , deviceId : String - , expiresInMs : Maybe Int + , homeServer : String , refreshToken : Maybe String , userId : String - , wellKnown : Maybe DiscoveryInformation } @@ -113,23 +30,19 @@ 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 ) + , ( "home_server", Just <| E.string data.homeServer ) , ( "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.map4 + (\a b c d -> + { accessToken = a, homeServer = b, refreshToken = c, userId = d } ) (D.field "access_token" D.string) - (D.field "device_id" D.string) - (opField "expires_in_ms" D.int) + (D.field "home_server" D.string) (opField "refresh_token" D.string) (D.field "user_id" D.string) - (opField "well_known" discoveryInformationDecoder) diff --git a/src/Internal/Api/LoginWithUsernameAndPassword/V1/Login.yaml b/src/Internal/Api/LoginWithUsernameAndPassword/V1/Login.yaml index 77711c8..e9eef51 100644 --- a/src/Internal/Api/LoginWithUsernameAndPassword/V1/Login.yaml +++ b/src/Internal/Api/LoginWithUsernameAndPassword/V1/Login.yaml @@ -2,44 +2,17 @@ version: V_1 name: Login objects: LoggedInResponse: - description: Confirmation that the user has successfully logged in. + description: Confirmation that the user successfully logged in. fields: access_token: type: string required: true - device_id: + home_server: 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 diff --git a/src/Internal/Api/LoginWithUsernameAndPassword/V2/SpecObjects.elm b/src/Internal/Api/LoginWithUsernameAndPassword/V2/SpecObjects.elm new file mode 100644 index 0000000..002078c --- /dev/null +++ b/src/Internal/Api/LoginWithUsernameAndPassword/V2/SpecObjects.elm @@ -0,0 +1,50 @@ +module Internal.Api.LoginWithUsernameAndPassword.V2.SpecObjects exposing + ( LoggedInResponse + , encodeLoggedInResponse + , loggedInResponseDecoder + ) + +{-| Automatically generated 'Login' + +Last generated at Unix time 1679075857 + +-} + +import Internal.Tools.EncodeExtra exposing (maybeObject) +import Json.Decode as D +import Json.Encode as E + + +{-| Confirmation that the user successfully logged in. +-} +type alias LoggedInResponse = + { accessToken : String + , deviceId : Maybe String + , homeServer : String + , refreshToken : Maybe String + , userId : String + } + + +encodeLoggedInResponse : LoggedInResponse -> E.Value +encodeLoggedInResponse data = + maybeObject + [ ( "access_token", Just <| E.string data.accessToken ) + , ( "device_id", Maybe.map E.string data.deviceId ) + , ( "home_server", Just <| E.string data.homeServer ) + , ( "refresh_token", Nothing ) + , ( "user_id", Just <| E.string data.userId ) + ] + + +loggedInResponseDecoder : D.Decoder LoggedInResponse +loggedInResponseDecoder = + D.map5 + (\a b c d e -> + { accessToken = a, deviceId = b, homeServer = c, refreshToken = d, userId = e } + ) + (D.field "access_token" D.string) + (D.map Just <| D.field "device_id" D.string) + (D.field "home_server" D.string) + (D.succeed Nothing) + (D.field "user_id" D.string) diff --git a/src/Internal/Api/LoginWithUsernameAndPassword/V2/SpecObjects.yaml b/src/Internal/Api/LoginWithUsernameAndPassword/V2/SpecObjects.yaml new file mode 100644 index 0000000..8a7f4b3 --- /dev/null +++ b/src/Internal/Api/LoginWithUsernameAndPassword/V2/SpecObjects.yaml @@ -0,0 +1,21 @@ +version: V_2 +name: Login +objects: + LoggedInResponse: + description: Confirmation that the user successfully logged in. + fields: + access_token: + type: string + required: true + device_id: + type: string + required: now + home_server: + type: string + required: true + refresh_token: + type: string + required: never + user_id: + type: string + required: true diff --git a/src/Internal/Api/LoginWithUsernameAndPassword/V2/Upcast.elm b/src/Internal/Api/LoginWithUsernameAndPassword/V2/Upcast.elm new file mode 100644 index 0000000..c36c829 --- /dev/null +++ b/src/Internal/Api/LoginWithUsernameAndPassword/V2/Upcast.elm @@ -0,0 +1,14 @@ +module Internal.Api.LoginWithUsernameAndPassword.V2.Upcast exposing (..) + +import Internal.Api.LoginWithUsernameAndPassword.V1.Login as PO +import Internal.Api.LoginWithUsernameAndPassword.V2.SpecObjects as SO + + +upcastLoggedInResponse : PO.LoggedInResponse -> SO.LoggedInResponse +upcastLoggedInResponse old = + { accessToken = old.accessToken + , deviceId = Nothing + , homeServer = old.homeServer + , refreshToken = old.refreshToken + , userId = old.userId + } diff --git a/src/Internal/Api/LoginWithUsernameAndPassword/V3/SpecObjects.elm b/src/Internal/Api/LoginWithUsernameAndPassword/V3/SpecObjects.elm new file mode 100644 index 0000000..914d99b --- /dev/null +++ b/src/Internal/Api/LoginWithUsernameAndPassword/V3/SpecObjects.elm @@ -0,0 +1,50 @@ +module Internal.Api.LoginWithUsernameAndPassword.V3.SpecObjects exposing + ( LoggedInResponse + , encodeLoggedInResponse + , loggedInResponseDecoder + ) + +{-| Automatically generated 'Login' + +Last generated at Unix time 1679075857 + +-} + +import Internal.Tools.EncodeExtra exposing (maybeObject) +import Json.Decode as D +import Json.Encode as E + + +{-| Confirmation that the user successfully logged in. +-} +type alias LoggedInResponse = + { accessToken : String + , deviceId : Maybe String + , homeServer : Maybe String + , refreshToken : Maybe String + , userId : String + } + + +encodeLoggedInResponse : LoggedInResponse -> E.Value +encodeLoggedInResponse data = + maybeObject + [ ( "access_token", Just <| E.string data.accessToken ) + , ( "device_id", Maybe.map E.string data.deviceId ) + , ( "home_server", Nothing ) + , ( "refresh_token", Nothing ) + , ( "user_id", Just <| E.string data.userId ) + ] + + +loggedInResponseDecoder : D.Decoder LoggedInResponse +loggedInResponseDecoder = + D.map5 + (\a b c d e -> + { accessToken = a, deviceId = b, homeServer = c, refreshToken = d, userId = e } + ) + (D.field "access_token" D.string) + (D.map Just <| D.field "device_id" D.string) + (D.succeed Nothing) + (D.succeed Nothing) + (D.field "user_id" D.string) diff --git a/src/Internal/Api/LoginWithUsernameAndPassword/V3/SpecObjects.yaml b/src/Internal/Api/LoginWithUsernameAndPassword/V3/SpecObjects.yaml new file mode 100644 index 0000000..7d83e47 --- /dev/null +++ b/src/Internal/Api/LoginWithUsernameAndPassword/V3/SpecObjects.yaml @@ -0,0 +1,21 @@ +version: V_3 +name: Login +objects: + LoggedInResponse: + description: Confirmation that the user successfully logged in. + fields: + access_token: + type: string + required: true + device_id: + type: string + required: now + home_server: + type: string + required: never + refresh_token: + type: string + required: never + user_id: + type: string + required: true diff --git a/src/Internal/Api/LoginWithUsernameAndPassword/V3/Upcast.elm b/src/Internal/Api/LoginWithUsernameAndPassword/V3/Upcast.elm new file mode 100644 index 0000000..a3c4670 --- /dev/null +++ b/src/Internal/Api/LoginWithUsernameAndPassword/V3/Upcast.elm @@ -0,0 +1,14 @@ +module Internal.Api.LoginWithUsernameAndPassword.V3.Upcast exposing (..) + +import Internal.Api.LoginWithUsernameAndPassword.V2.SpecObjects as PO +import Internal.Api.LoginWithUsernameAndPassword.V3.SpecObjects as SO + + +upcastLoggedInResponse : PO.LoggedInResponse -> SO.LoggedInResponse +upcastLoggedInResponse old = + { accessToken = old.accessToken + , deviceId = Nothing + , homeServer = Just old.homeServer + , refreshToken = old.refreshToken + , userId = old.userId + } diff --git a/src/Internal/Api/LoginWithUsernameAndPassword/V4/SpecObjects.elm b/src/Internal/Api/LoginWithUsernameAndPassword/V4/SpecObjects.elm new file mode 100644 index 0000000..52cd2bf --- /dev/null +++ b/src/Internal/Api/LoginWithUsernameAndPassword/V4/SpecObjects.elm @@ -0,0 +1,135 @@ +module Internal.Api.LoginWithUsernameAndPassword.V4.SpecObjects exposing + ( DiscoveryInformation + , HomeserverInformation + , IdentityServerInformation + , LoggedInResponse + , discoveryInformationDecoder + , encodeDiscoveryInformation + , encodeHomeserverInformation + , encodeIdentityServerInformation + , encodeLoggedInResponse + , homeserverInformationDecoder + , identityServerInformationDecoder + , loggedInResponseDecoder + ) + +{-| Automatically generated 'Login' + +Last generated at Unix time 1679075857 + +-} + +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 successfully logged in. +-} +type alias LoggedInResponse = + { accessToken : String + , deviceId : Maybe String + , homeServer : Maybe String + , refreshToken : Maybe String + , userId : String + , wellKnown : Maybe DiscoveryInformation + } + + +encodeLoggedInResponse : LoggedInResponse -> E.Value +encodeLoggedInResponse data = + maybeObject + [ ( "access_token", Just <| E.string data.accessToken ) + , ( "device_id", Maybe.map E.string data.deviceId ) + , ( "home_server", Nothing ) + , ( "refresh_token", Nothing ) + , ( "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, homeServer = c, refreshToken = d, userId = e, wellKnown = f } + ) + (D.field "access_token" D.string) + (D.map Just <| D.field "device_id" D.string) + (D.succeed Nothing) + (D.succeed Nothing) + (D.field "user_id" D.string) + (opField "well_known" discoveryInformationDecoder) diff --git a/src/Internal/Api/LoginWithUsernameAndPassword/V4/SpecObjects.yaml b/src/Internal/Api/LoginWithUsernameAndPassword/V4/SpecObjects.yaml new file mode 100644 index 0000000..6e07157 --- /dev/null +++ b/src/Internal/Api/LoginWithUsernameAndPassword/V4/SpecObjects.yaml @@ -0,0 +1,45 @@ +version: V_3 +name: Login +objects: + LoggedInResponse: + description: Confirmation that the user successfully logged in. + fields: + access_token: + type: string + required: true + device_id: + type: string + required: now + home_server: + type: string + required: never + refresh_token: + type: string + required: never + 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 diff --git a/src/Internal/Api/LoginWithUsernameAndPassword/V4/Upcast.elm b/src/Internal/Api/LoginWithUsernameAndPassword/V4/Upcast.elm new file mode 100644 index 0000000..5de684d --- /dev/null +++ b/src/Internal/Api/LoginWithUsernameAndPassword/V4/Upcast.elm @@ -0,0 +1,15 @@ +module Internal.Api.LoginWithUsernameAndPassword.V4.Upcast exposing (..) + +import Internal.Api.LoginWithUsernameAndPassword.V3.SpecObjects as PO +import Internal.Api.LoginWithUsernameAndPassword.V4.SpecObjects as SO + + +upcastLoggedInResponse : PO.LoggedInResponse -> SO.LoggedInResponse +upcastLoggedInResponse old = + { accessToken = old.accessToken + , deviceId = old.deviceId + , homeServer = old.homeServer + , refreshToken = old.refreshToken + , userId = old.userId + , wellKnown = Nothing + } diff --git a/src/Internal/Api/LoginWithUsernameAndPassword/V5/Login.elm b/src/Internal/Api/LoginWithUsernameAndPassword/V5/Login.elm new file mode 100644 index 0000000..e4c58d7 --- /dev/null +++ b/src/Internal/Api/LoginWithUsernameAndPassword/V5/Login.elm @@ -0,0 +1,138 @@ +module Internal.Api.LoginWithUsernameAndPassword.V5.Login exposing + ( DiscoveryInformation + , HomeserverInformation + , IdentityServerInformation + , LoggedInResponse + , discoveryInformationDecoder + , encodeDiscoveryInformation + , encodeHomeserverInformation + , encodeIdentityServerInformation + , encodeLoggedInResponse + , homeserverInformationDecoder + , identityServerInformationDecoder + , loggedInResponseDecoder + ) + +{-| Automatically generated 'Login' + +Last generated at Unix time 1679075857 + +-} + +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 : Maybe String + , expiresInMs : Maybe Int + , homeServer : Maybe String + , refreshToken : Maybe String + , userId : String + , wellKnown : Maybe DiscoveryInformation + } + + +encodeLoggedInResponse : LoggedInResponse -> E.Value +encodeLoggedInResponse data = + maybeObject + [ ( "access_token", Just <| E.string data.accessToken ) + , ( "device_id", Maybe.map E.string data.deviceId ) + , ( "expires_in_ms", Maybe.map E.int data.expiresInMs ) + , ( "home_server", Nothing ) + , ( "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.map7 + (\a b c d e f g -> + { accessToken = a, deviceId = b, expiresInMs = c, homeServer = d, refreshToken = e, userId = f, wellKnown = g } + ) + (D.field "access_token" D.string) + (D.map Just <| D.field "device_id" D.string) + (opField "expires_in_ms" D.int) + (D.succeed Nothing) + (opField "refresh_token" D.string) + (D.field "user_id" D.string) + (opField "well_known" discoveryInformationDecoder) diff --git a/src/Internal/Api/LoginWithUsernameAndPassword/V5/Login.yaml b/src/Internal/Api/LoginWithUsernameAndPassword/V5/Login.yaml new file mode 100644 index 0000000..f959f26 --- /dev/null +++ b/src/Internal/Api/LoginWithUsernameAndPassword/V5/Login.yaml @@ -0,0 +1,48 @@ +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: now + expires_in_ms: + type: int + required: false + home_server: + type: string + required: never + 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 diff --git a/src/Internal/Api/LoginWithUsernameAndPassword/V5/Upcast.elm b/src/Internal/Api/LoginWithUsernameAndPassword/V5/Upcast.elm new file mode 100644 index 0000000..74651e3 --- /dev/null +++ b/src/Internal/Api/LoginWithUsernameAndPassword/V5/Upcast.elm @@ -0,0 +1,16 @@ +module Internal.Api.LoginWithUsernameAndPassword.V5.Upcast exposing (..) + +import Internal.Api.LoginWithUsernameAndPassword.V4.SpecObjects as PO +import Internal.Api.LoginWithUsernameAndPassword.V5.Login as SO + + +upcastLoggedInResponse : PO.LoggedInResponse -> SO.LoggedInResponse +upcastLoggedInResponse old = + { accessToken = old.accessToken + , deviceId = old.deviceId + , expiresInMs = Nothing + , homeServer = old.homeServer + , refreshToken = old.refreshToken + , userId = old.userId + , wellKnown = old.wellKnown + } diff --git a/src/Internal/Api/VaultUpdate.elm b/src/Internal/Api/VaultUpdate.elm index 968bb59..5b655e0 100644 --- a/src/Internal/Api/VaultUpdate.elm +++ b/src/Internal/Api/VaultUpdate.elm @@ -79,21 +79,25 @@ accessToken ctoken = |> always AccessToken t -> - { contextChange = Context.setAccessToken { accessToken = t, usernameAndPassword = Nothing } + { contextChange = Context.setAccessToken { accessToken = t, loginParts = Nothing } , messages = [] } |> Chain.TaskChainPiece |> Task.succeed |> always - UsernameAndPassword { username, password, token } -> + UsernameAndPassword { username, password, token, deviceId, initialDeviceDisplayName } -> case token of Just t -> accessToken (AccessToken t) Nothing -> loginWithUsernameAndPassword - { username = username, password = password } + { username = username + , password = password + , deviceId = deviceId + , initialDeviceDisplayName = initialDeviceDisplayName + } {-| Get an event from the API. @@ -188,7 +192,7 @@ loginWithUsernameAndPassword input = { contextChange = Context.setAccessToken { accessToken = output.accessToken - , usernameAndPassword = Just input + , loginParts = Just input } , messages = [ LoggedInWithUsernameAndPassword input output ] } diff --git a/src/Internal/Api/Versions/V1/Versions.elm b/src/Internal/Api/Versions/V1/Versions.elm index 9195e42..7da25f4 100644 --- a/src/Internal/Api/Versions/V1/Versions.elm +++ b/src/Internal/Api/Versions/V1/Versions.elm @@ -6,12 +6,12 @@ module Internal.Api.Versions.V1.Versions exposing {-| Automatically generated 'Versions' -Last generated at Unix time 1677064309 +Last generated at Unix time 1679075857 -} import Dict exposing (Dict) -import Internal.Tools.DecodeExtra exposing (opField, opFieldWithDefault) +import Internal.Tools.DecodeExtra exposing (opFieldWithDefault) import Internal.Tools.EncodeExtra exposing (maybeObject) import Json.Decode as D import Json.Encode as E diff --git a/src/Internal/Tools/Context.elm b/src/Internal/Tools/Context.elm index a7a959d..7bfa931 100644 --- a/src/Internal/Tools/Context.elm +++ b/src/Internal/Tools/Context.elm @@ -24,13 +24,17 @@ type Context a , baseUrl : String , sentEvent : String , transactionId : String - , usernameAndPassword : Maybe UsernameAndPassword + , loginParts : Maybe LoginParts , versions : List String } -type alias UsernameAndPassword = - { username : String, password : String } +type alias LoginParts = + { deviceId : Maybe String + , initialDeviceDisplayName : Maybe String + , password : String + , username : String + } type alias VB a = @@ -54,7 +58,7 @@ init = , baseUrl = L.baseUrl , sentEvent = L.eventId , transactionId = L.transactionId - , usernameAndPassword = Nothing + , loginParts = Nothing , versions = L.versions } @@ -89,9 +93,9 @@ getTransactionId (Context { transactionId }) = {-| Get the username and password of the user, if present. -} -getUsernameAndPassword : Context { a | accessToken : () } -> Maybe UsernameAndPassword -getUsernameAndPassword (Context { usernameAndPassword }) = - usernameAndPassword +getLoginParts : Context { a | accessToken : () } -> Maybe LoginParts +getLoginParts (Context { loginParts }) = + loginParts {-| Get the supported spec versions from the Context. @@ -103,9 +107,9 @@ getVersions (Context { versions }) = {-| Insert an access token into the context. -} -setAccessToken : { accessToken : String, usernameAndPassword : Maybe UsernameAndPassword } -> Context a -> Context { a | accessToken : () } -setAccessToken { accessToken, usernameAndPassword } (Context data) = - Context { data | accessToken = accessToken, usernameAndPassword = usernameAndPassword } +setAccessToken : { accessToken : String, loginParts : Maybe LoginParts } -> Context a -> Context { a | accessToken : () } +setAccessToken { accessToken, loginParts } (Context data) = + Context { data | accessToken = accessToken, loginParts = loginParts } {-| Insert a base url into the context. diff --git a/src/Internal/Tools/LoginValues.elm b/src/Internal/Tools/LoginValues.elm index e877b34..9624919 100644 --- a/src/Internal/Tools/LoginValues.elm +++ b/src/Internal/Tools/LoginValues.elm @@ -4,7 +4,13 @@ module Internal.Tools.LoginValues exposing (..) type AccessToken = NoAccess | AccessToken String - | UsernameAndPassword { username : String, password : String, token : Maybe String } + | UsernameAndPassword + { deviceId : Maybe String + , initialDeviceDisplayName : Maybe String + , password : String + , token : Maybe String + , username : String + } defaultAccessToken : AccessToken @@ -23,6 +29,8 @@ fromUsernameAndPassword username password = { username = username , password = password , token = Nothing + , deviceId = Nothing + , initialDeviceDisplayName = Nothing } @@ -48,37 +56,29 @@ addToken s t = AccessToken _ -> AccessToken s - UsernameAndPassword { username, password } -> + UsernameAndPassword data -> UsernameAndPassword - { username = username - , password = password - , token = Just s - } + { data | token = Just s } addUsernameAndPassword : { username : String, password : String } -> AccessToken -> AccessToken addUsernameAndPassword { username, password } t = case t of NoAccess -> - UsernameAndPassword - { username = username - , password = password - , token = Nothing - } + fromUsernameAndPassword username password AccessToken a -> UsernameAndPassword { username = username , password = password , token = Just a + , deviceId = Nothing + , initialDeviceDisplayName = Nothing } - UsernameAndPassword { token } -> + UsernameAndPassword data -> UsernameAndPassword - { username = username - , password = password - , token = token - } + { data | username = username, password = password } removeToken : AccessToken -> AccessToken @@ -90,9 +90,6 @@ removeToken t = AccessToken _ -> NoAccess - UsernameAndPassword { username, password } -> + UsernameAndPassword data -> UsernameAndPassword - { username = username - , password = password - , token = Nothing - } + { data | token = Nothing } diff --git a/src/Internal/Values/RoomInvite.elm b/src/Internal/Values/RoomInvite.elm index 6c5150c..9819f5b 100644 --- a/src/Internal/Values/RoomInvite.elm +++ b/src/Internal/Values/RoomInvite.elm @@ -4,7 +4,6 @@ module Internal.Values.RoomInvite exposing (..) -} import Dict exposing (Dict) -import Internal.Values.Room exposing (IRoom) import Json.Encode as E diff --git a/src/Matrix/RoomInvite.elm b/src/Matrix/RoomInvite.elm index c9507b8..8440cc9 100644 --- a/src/Matrix/RoomInvite.elm +++ b/src/Matrix/RoomInvite.elm @@ -1,4 +1,8 @@ -module Matrix.RoomInvite exposing (RoomInvite, accept, reject, acceptWithReason, rejectWithReason) +module Matrix.RoomInvite exposing + ( RoomInvite, accept, reject, acceptWithReason, rejectWithReason + , roomId + , sender, stateKey, contentType, content + ) {-| Sometimes, your user will be invited to a new room! This module offers you a few simple handles to deal with such invites - @@ -18,7 +22,7 @@ Be careful though, anyone can invite you to any room! This means that room invit may contain offensive, shocking or other unwanted content that the user may not want to see. -@docs RoomInviteEvent getEvent, getAllEvents +@docs roomId, RoomInviteEvent, getEvent, getAllEvents Once you have the event you want, you can explore it with the following functions.