From fc5d01c775bde656b6d69954189522d138efe022 Mon Sep 17 00:00:00 2001
From: Nicolas Werner <nicolas.werner@hotmail.de>
Date: Mon, 8 Nov 2021 16:59:20 +0100
Subject: [PATCH] Fix access token and device id being unset after registration

---
 include/mtxclient/http/client.hpp | 13 --------
 lib/http/client.cpp               | 31 +++++--------------
 tests/client_api.cpp              | 49 +++++++++++++++++++------------
 3 files changed, 39 insertions(+), 54 deletions(-)

diff --git a/include/mtxclient/http/client.hpp b/include/mtxclient/http/client.hpp
index 35ba83b19..e717b3897 100644
--- a/include/mtxclient/http/client.hpp
+++ b/include/mtxclient/http/client.hpp
@@ -258,19 +258,6 @@ public:
     //! Call set_server with the returned homeserver url after this
     void well_known(Callback<mtx::responses::WellKnown> cb);
 
-    //! Register
-    //! If this fails with 401, continue with the flows returned in the error struct
-    void registration(const std::string &user,
-                      const std::string &pass,
-                      Callback<mtx::responses::Register> cb);
-
-    //! Register and additionally provide an auth dict. This needs to be called, if the initial
-    //! register failed with 401
-    void registration(const std::string &user,
-                      const std::string &pass,
-                      const user_interactive::Auth &auth,
-                      Callback<mtx::responses::Register> cb);
-
     //! Register with an UIA handler so you don't need to repeat the request manually.
     void registration(const std::string &user,
                       const std::string &pass,
diff --git a/lib/http/client.cpp b/lib/http/client.cpp
index 38fc62fa4..f058bf278 100644
--- a/lib/http/client.cpp
+++ b/lib/http/client.cpp
@@ -880,27 +880,6 @@ Client::redact_event(const std::string &room_id,
     put<nlohmann::json, mtx::responses::EventId>(api_path, body, callback);
 }
 
-void
-Client::registration(const std::string &user,
-                     const std::string &pass,
-                     Callback<mtx::responses::Register> callback)
-{
-    nlohmann::json req = {{"username", user}, {"password", pass}};
-
-    post<nlohmann::json, mtx::responses::Register>("/client/r0/register", req, callback, false);
-}
-
-void
-Client::registration(const std::string &user,
-                     const std::string &pass,
-                     const mtx::user_interactive::Auth &auth,
-                     Callback<mtx::responses::Register> callback)
-{
-    nlohmann::json req = {{"username", user}, {"password", pass}, {"auth", auth}};
-
-    post<nlohmann::json, mtx::responses::Register>("/client/r0/register", req, callback, false);
-}
-
 void
 Client::registration(const std::string &user,
                      const std::string &pass,
@@ -917,12 +896,18 @@ Client::registration(const std::string &user,
         post<nlohmann::json, mtx::responses::Register>(
           "/client/r0/register",
           request,
-          [cb, h](auto &r, RequestErr e) {
+          [this, cb, h](auto &r, RequestErr e) {
               if (e && e->status_code == 401) {
                   std::cout << e->matrix_error.error << "\n";
                   h.prompt(h, e->matrix_error.unauthorized);
-              } else
+              } else {
+                  if (!e && !r.access_token.empty()) {
+                      this->user_id_      = r.user_id;
+                      this->device_id_    = r.device_id;
+                      this->access_token_ = r.access_token;
+                  }
                   cb(r, e);
+              }
           },
           false);
     };
diff --git a/tests/client_api.cpp b/tests/client_api.cpp
index b52988f4a..199588dfd 100644
--- a/tests/client_api.cpp
+++ b/tests/client_api.cpp
@@ -24,10 +24,16 @@ TEST(ClientAPI, Register)
 {
     auto user = make_test_client();
 
-    user->registration("alice", "secret", [](const mtx::responses::Register &, RequestErr err) {
-        ASSERT_TRUE(err);
-        EXPECT_EQ(mtx::errors::to_string(err->matrix_error.errcode), "M_USER_IN_USE");
-    });
+    user->registration("alice",
+                       "secret",
+                       mtx::http::UIAHandler(
+                         [](const mtx::http::UIAHandler &,
+                            const mtx::user_interactive::Unauthorized &) { EXPECT_TRUE(false); }),
+                       [](const mtx::responses::Register &, RequestErr err) {
+                           ASSERT_TRUE(err);
+                           EXPECT_EQ(mtx::errors::to_string(err->matrix_error.errcode),
+                                     "M_USER_IN_USE");
+                       });
 
     auto username = utils::random_token(10, false);
 
@@ -37,23 +43,30 @@ TEST(ClientAPI, Register)
     }
 
     user->registration(
-      username, "secret", [user, username](const mtx::responses::Register &, RequestErr err) {
+      username,
+      "secret",
+      mtx::http::UIAHandler([](const mtx::http::UIAHandler &h,
+                               const mtx::user_interactive::Unauthorized &unauthorized) {
+          EXPECT_EQ(unauthorized.flows.size(), 1);
+          EXPECT_EQ(unauthorized.flows[0].stages[0], "m.login.dummy");
+
+          mtx::user_interactive::Auth auth{unauthorized.session,
+                                           mtx::user_interactive::auth::Dummy{}};
+          h.next(auth);
+      }),
+      [user, username](const mtx::responses::Register &res, RequestErr err) {
           if (!err || err->matrix_error.unauthorized.flows.size() == 0)
               return;
 
-          EXPECT_EQ(err->matrix_error.unauthorized.flows.size(), 1);
-          EXPECT_EQ(err->matrix_error.unauthorized.flows[0].stages[0], "m.login.dummy");
-
-          user->registration(
-            username,
-            "secret",
-            {err->matrix_error.unauthorized.session, mtx::user_interactive::auth::Dummy{}},
-            [username](const mtx::responses::Register &res, RequestErr err) {
-                const auto user_id = "@" + username + ":" + server_name();
-
-                check_error(err);
-                EXPECT_EQ(res.user_id.to_string(), user_id);
-            });
+          check_error(err);
+          const auto user_id = "@" + username + ":" + server_name();
+          EXPECT_EQ(res.user_id.to_string(), user_id);
+
+          EXPECT_EQ(user->user_id().to_string(), user_id);
+          EXPECT_FALSE(user->access_token().empty());
+          EXPECT_EQ(user->access_token(), res.access_token);
+          EXPECT_FALSE(user->device_id().empty());
+          EXPECT_EQ(user->device_id(), res.device_id);
       });
 
     user->close();
-- 
GitLab