• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

realm / realm-core / github_pull_request_312964

19 Feb 2025 07:31PM UTC coverage: 90.814% (-0.3%) from 91.119%
github_pull_request_312964

Pull #8071

Evergreen

web-flow
Bump serialize-javascript and mocha

Bumps [serialize-javascript](https://github.com/yahoo/serialize-javascript) to 6.0.2 and updates ancestor dependency [mocha](https://github.com/mochajs/mocha). These dependencies need to be updated together.


Updates `serialize-javascript` from 6.0.0 to 6.0.2
- [Release notes](https://github.com/yahoo/serialize-javascript/releases)
- [Commits](https://github.com/yahoo/serialize-javascript/compare/v6.0.0...v6.0.2)

Updates `mocha` from 10.2.0 to 10.8.2
- [Release notes](https://github.com/mochajs/mocha/releases)
- [Changelog](https://github.com/mochajs/mocha/blob/main/CHANGELOG.md)
- [Commits](https://github.com/mochajs/mocha/compare/v10.2.0...v10.8.2)

---
updated-dependencies:
- dependency-name: serialize-javascript
  dependency-type: indirect
- dependency-name: mocha
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Pull Request #8071: Bump serialize-javascript and mocha

96552 of 179126 branches covered (53.9%)

212672 of 234185 relevant lines covered (90.81%)

3115802.0 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

91.92
/src/realm/object-store/sync/app_user.cpp
1
////////////////////////////////////////////////////////////////////////////
2
//
3
// Copyright 2024 Realm Inc.
4
//
5
// Licensed under the Apache License, Version 2.0 (the "License");
6
// you may not use this file except in compliance with the License.
7
// You may obtain a copy of the License at
8
//
9
// http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing, software
12
// distributed under the License is distributed on an "AS IS" BASIS,
13
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
// See the License for the specific language governing permissions and
15
// limitations under the License.
16
//
17
////////////////////////////////////////////////////////////////////////////
18

19
#include <realm/object-store/sync/app_user.hpp>
20

21
#include <realm/object-store/sync/app.hpp>
22
#include <realm/object-store/sync/app_credentials.hpp>
23
#include <realm/object-store/sync/generic_network_transport.hpp>
24
#include <realm/object-store/sync/impl/app_metadata.hpp>
25
#include <realm/object-store/sync/impl/sync_file.hpp>
26
#include <realm/object-store/sync/mongo_client.hpp>
27
#include <realm/object-store/sync/sync_manager.hpp>
28

29
namespace realm::app {
30

31
UserIdentity::UserIdentity(const std::string& id, const std::string& provider_type)
32
    : id(id)
3,020✔
33
    , provider_type(provider_type)
3,020✔
34
{
3,020✔
35
}
3,020✔
36

37
User::User(Private, std::shared_ptr<app::App> app, std::string_view user_id)
38
    : m_app(std::move(app))
4,780✔
39
    , m_app_id(m_app->app_id())
4,780✔
40
    , m_user_id(user_id)
4,780✔
41
{
4,780✔
42
    REALM_ASSERT(m_app);
4,780✔
43
    m_app->register_sync_user(*this);
4,780✔
44
}
4,780✔
45

46
User::~User()
47
{
4,780✔
48
    if (m_app) {
4,780✔
49
        m_app->unregister_sync_user(*this);
4,757✔
50
    }
4,757✔
51
}
4,780✔
52

53
std::string User::user_id() const noexcept
54
{
20,356✔
55
    return m_user_id;
20,356✔
56
}
20,356✔
57

58
std::string User::app_id() const noexcept
59
{
×
60
    return m_app_id;
×
61
}
×
62

63
std::vector<std::string> User::legacy_identities() const
64
{
14✔
65
    util::CheckedLockGuard lock(m_mutex);
14✔
66
    return m_data.legacy_identities;
14✔
67
}
14✔
68

69
std::string User::access_token() const
70
{
3,536✔
71
    util::CheckedLockGuard lock(m_mutex);
3,536✔
72
    return m_data.access_token.token;
3,536✔
73
}
3,536✔
74

75
std::string User::refresh_token() const
76
{
112✔
77
    util::CheckedLockGuard lock(m_mutex);
112✔
78
    return m_data.refresh_token.token;
112✔
79
}
112✔
80

81
SyncUser::State User::state() const
82
{
8,388✔
83
    util::CheckedLockGuard lock(m_mutex);
8,388✔
84
    if (!m_app)
8,388✔
85
        return SyncUser::State::Removed;
32✔
86
    return m_data.access_token ? SyncUser::State::LoggedIn : SyncUser::State::LoggedOut;
8,356✔
87
}
8,388✔
88

89
bool User::is_anonymous() const
90
{
34✔
91
    util::CheckedLockGuard lock(m_mutex);
34✔
92
    return do_is_anonymous();
34✔
93
}
34✔
94

95
bool User::do_is_anonymous() const
96
{
34✔
97
    return m_data.access_token && m_data.identities.size() == 1 &&
34✔
98
           m_data.identities[0].provider_type == app::IdentityProviderAnonymous;
34✔
99
}
34✔
100

101
std::string User::device_id() const
102
{
1✔
103
    util::CheckedLockGuard lock(m_mutex);
1✔
104
    return m_data.device_id;
1✔
105
}
1✔
106

107
bool User::has_device_id() const
108
{
1✔
109
    // The server will sometimes send us an all-zero device ID as a way to
110
    // explicitly signal that it did not generate a device ID for this login.
111
    util::CheckedLockGuard lock(m_mutex);
1✔
112
    return !m_data.device_id.empty() && m_data.device_id != "000000000000000000000000";
1✔
113
}
1✔
114

115
UserProfile User::user_profile() const
116
{
7✔
117
    util::CheckedLockGuard lock(m_mutex);
7✔
118
    return m_data.profile;
7✔
119
}
7✔
120

121
std::vector<UserIdentity> User::identities() const
122
{
15✔
123
    util::CheckedLockGuard lock(m_mutex);
15✔
124
    return m_data.identities;
15✔
125
}
15✔
126

127
std::optional<bson::BsonDocument> User::custom_data() const
128
{
2✔
129
    util::CheckedLockGuard lock(m_mutex);
2✔
130
    return m_data.access_token.user_data;
2✔
131
}
2✔
132

133
std::shared_ptr<App> User::app() const
134
{
113✔
135
    util::CheckedLockGuard lock(m_mutex);
113✔
136
    return m_app;
113✔
137
}
113✔
138

139
SyncManager* User::sync_manager()
140
{
1,129✔
141
    util::CheckedLockGuard lock(m_mutex);
1,129✔
142
    return m_app ? m_app->sync_manager().get() : nullptr;
1,129✔
143
}
1,129✔
144

145
app::MongoClient User::mongo_client(const std::string& service_name)
146
{
35✔
147
    util::CheckedLockGuard lock(m_mutex);
35✔
148
    return app::MongoClient(shared_from_this(), m_app->app_service_client(), service_name);
35✔
149
}
35✔
150

151
bool User::access_token_refresh_required() const
152
{
879✔
153
    using namespace std::chrono;
879✔
154
    constexpr size_t buffer_seconds = 5; // arbitrary
879✔
155
    util::CheckedLockGuard lock(m_mutex);
879✔
156
    const auto now = duration_cast<seconds>(system_clock::now().time_since_epoch()).count() +
879✔
157
                     m_seconds_to_adjust_time_for_testing.load(std::memory_order_relaxed);
879✔
158
    const auto threshold = now - buffer_seconds;
879✔
159
    return m_data.access_token && m_data.access_token.expires_at < static_cast<int64_t>(threshold);
879✔
160
}
879✔
161

162
void User::log_out()
163
{
3✔
164
    if (auto app = this->app()) {
3✔
165
        app->log_out(shared_from_this(), nullptr);
3✔
166
    }
3✔
167
}
3✔
168

169
void User::detach_and_tear_down()
170
{
30✔
171
    std::shared_ptr<App> app;
30✔
172
    {
30✔
173
        util::CheckedLockGuard lk(m_mutex);
30✔
174
        m_data.access_token.token.clear();
30✔
175
        m_data.refresh_token.token.clear();
30✔
176
        app = std::exchange(m_app, nullptr);
30✔
177
    }
30✔
178

179
    if (app) {
30✔
180
        app->sync_manager()->update_sessions_for(*this, SyncUser::State::LoggedIn, SyncUser::State::Removed, {});
23✔
181
        app->unregister_sync_user(*this);
23✔
182
    }
23✔
183
}
30✔
184

185
void User::update_data_for_testing(util::FunctionRef<void(UserData&)> fn)
186
{
14✔
187
    UserData data;
14✔
188
    {
14✔
189
        util::CheckedLockGuard lock(m_mutex);
14✔
190
        data = m_data;
14✔
191
    }
14✔
192
    fn(data);
14✔
193
    update_backing_data(std::move(data));
14✔
194
}
14✔
195

196
void User::update_backing_data(std::optional<UserData>&& data)
197
{
7,300✔
198
    if (!data) {
7,300✔
199
        detach_and_tear_down();
26✔
200
        emit_change_to_subscribers(*this);
26✔
201
        return;
26✔
202
    }
26✔
203

204
    std::string new_token;
7,274✔
205
    SyncUser::State old_state;
7,274✔
206
    SyncUser::State new_state = data->access_token ? SyncUser::State::LoggedIn : SyncUser::State::LoggedOut;
7,274✔
207
    std::shared_ptr<SyncManager> sync_manager;
7,274✔
208
    {
7,274✔
209
        util::CheckedLockGuard lock(m_mutex);
7,274✔
210
        if (!m_app) {
7,274✔
211
            return; // is already detached
×
212
        }
×
213
        sync_manager = m_app->sync_manager();
7,274✔
214
        old_state = m_data.access_token ? SyncUser::State::LoggedIn : SyncUser::State::LoggedOut;
7,274✔
215
        if (new_state == SyncUser::State::LoggedIn && data->access_token != m_data.access_token)
7,274✔
216
            new_token = data->access_token.token;
4,814✔
217
        m_data = std::move(*data);
7,274✔
218
    }
7,274✔
219

220
    sync_manager->update_sessions_for(*this, old_state, new_state, new_token);
×
221
    emit_change_to_subscribers(*this);
7,274✔
222
}
7,274✔
223

224
void User::request_log_out()
225
{
9✔
226
    if (auto app = this->app()) {
9✔
227
        auto new_state = is_anonymous() ? SyncUser::State::Removed : SyncUser::State::LoggedOut;
9✔
228
        app->m_metadata_store->log_out(m_user_id, new_state);
9✔
229
        update_backing_data(app->m_metadata_store->get_user(m_user_id));
9✔
230
    }
9✔
231
}
9✔
232

233
void User::request_refresh_location(util::UniqueFunction<void(util::Optional<app::AppError>)>&& completion)
234
{
24✔
235
    if (auto app = this->app()) {
24✔
236
        bool update_location = true;
24✔
237
        app->refresh_access_token(shared_from_this(), update_location, std::move(completion));
24✔
238
    }
24✔
239
}
24✔
240

241
void User::request_access_token(util::UniqueFunction<void(util::Optional<app::AppError>)>&& completion)
242
{
20✔
243
    if (auto app = this->app()) {
20✔
244
        bool update_location = false;
20✔
245
        app->refresh_access_token(shared_from_this(), update_location, std::move(completion));
20✔
246
    }
20✔
247
}
20✔
248

249
void User::track_realm(std::string_view path)
250
{
14✔
251
    if (auto app = this->app()) {
14✔
252
        app->m_metadata_store->add_realm_path(m_user_id, path);
14✔
253
    }
14✔
254
}
14✔
255

256
std::string User::create_file_action(SyncFileAction action, std::string_view original_path,
257
                                     std::optional<std::string> requested_recovery_dir)
258
{
37✔
259
    if (auto app = this->app()) {
37✔
260
        std::string recovery_path;
37✔
261
        if (action == SyncFileAction::BackUpThenDeleteRealm) {
37✔
262
            recovery_path =
37✔
263
                util::reserve_unique_file_name(app->m_file_manager->recovery_directory_path(requested_recovery_dir),
37✔
264
                                               util::create_timestamped_template("recovered_realm"));
37✔
265
        }
37✔
266
        app->m_metadata_store->create_file_action(action, original_path, recovery_path);
37✔
267
        return recovery_path;
37✔
268
    }
37✔
269
    return "";
×
270
}
37✔
271

272
void User::refresh_custom_data(util::UniqueFunction<void(util::Optional<app::AppError>)> completion_block)
273
    REQUIRES(!m_mutex)
274
{
6✔
275
    refresh_custom_data(false, std::move(completion_block));
6✔
276
}
6✔
277

278
void User::refresh_custom_data(bool update_location,
279
                               util::UniqueFunction<void(util::Optional<app::AppError>)> completion_block)
280
{
6✔
281
    if (auto app = this->app()) {
6✔
282
        app->refresh_custom_data(shared_from_this(), update_location, std::move(completion_block));
5✔
283
        return;
5✔
284
    }
5✔
285
    completion_block(app::AppError(
1✔
286
        ErrorCodes::ClientUserNotFound,
1✔
287
        util::format("Cannot initiate a refresh on user '%1' because the user has been removed", m_user_id)));
1✔
288
}
1✔
289

290
std::string User::path_for_realm(const SyncConfig& config, std::optional<std::string> custom_file_name) const
291
{
×
292
    if (auto app = this->app()) {
×
293
        return app->m_file_manager->path_for_realm(config, std::move(custom_file_name));
×
294
    }
×
295
    return "";
×
296
}
×
297
} // namespace realm::app
298

299
namespace std {
300
size_t hash<realm::app::UserIdentity>::operator()(const realm::app::UserIdentity& k) const
301
{
×
302
    return ((hash<string>()(k.id) ^ (hash<string>()(k.provider_type) << 1)) >> 1);
×
303
}
×
304
} // namespace std
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc