When refreshing the token, look up the user in a way that doesn't suffer from #1586 (#1587)

* When refreshing the token, look up the user in a way that doesn't suffer
from #1586

Expose a means of looking up a user by identity and server to avoid
problems if the same user identity exists for multiple servers, which
can happen when connecting to the same server via different hostnames.

* Return undefined if the user doesn't exist rather than returning an object wrapping a null SyncUser.
This commit is contained in:
Mark Rowe 2018-01-11 07:00:31 -08:00 committed by Kenneth Geisshirt
parent ce67446976
commit cd8db46aa7
3 changed files with 18 additions and 3 deletions

View File

@ -10,7 +10,9 @@ X.Y.Z Release notes
* [Object Server] Added JWT authenfication (#1548).
### Bug fixes
* Fixed a bug where `Realm.open` could unexpectedly raise a "Realm at path ... already opened with different schema version" error.
* Fix a bug where `Realm.open` could unexpectedly raise a "Realm at path ... already opened with different schema version" error.
* Increased request timeout for token refresh requests to 10 seconds. This
should help with failing token refreshes on a loaded server (#1586).
* Increased request timeout for token refresh requests to 10 seconds. This should help with failing token refreshes on a loaded server.
### Internal

View File

@ -138,7 +138,7 @@ function refreshAccessToken(user, localRealmPath, realmUrl) {
// Look up a fresh instance of the user.
// We do this because in React Native Remote Debugging
// `Realm.clearTestState()` will have invalidated the user object
const newUser = user.constructor.all[user.identity];
let newUser = user.constructor._getExistingUser(user.server, user.identity);
if (!newUser) {
return;
}

View File

@ -59,6 +59,7 @@ class UserClass : public ClassDefinition<T, SharedUser> {
using Value = js::Value<T>;
using Function = js::Function<T>;
using ReturnValue = js::ReturnValue<T>;
using Arguments = js::Arguments<T>;
public:
std::string const name = "User";
@ -81,10 +82,12 @@ public:
static void create_user(ContextType, FunctionType, ObjectType, size_t, const ValueType[], ReturnValue &);
static void admin_user(ContextType, FunctionType, ObjectType, size_t, const ValueType[], ReturnValue &);
static void get_existing_user(ContextType, ObjectType, Arguments, ReturnValue&);
MethodMap<T> const static_methods = {
{"createUser", wrap<create_user>},
{"_adminUser", wrap<admin_user>}
{"_adminUser", wrap<admin_user>},
{"_getExistingUser", wrap<get_existing_user>},
};
/*static void current_user(ContextType ctx, ObjectType object, ReturnValue &return_value);*/
@ -160,6 +163,16 @@ void UserClass<T>::admin_user(ContextType ctx, FunctionType, ObjectType this_obj
return_value.set(create_object<T, UserClass<T>>(ctx, user));
}
template<typename T>
void UserClass<T>::get_existing_user(ContextType ctx, ObjectType, Arguments arguments, ReturnValue& return_value) {
arguments.validate_count(2);
if (auto user = syncManagerShared().get_existing_logged_in_user(SyncUserIdentifier{
Value::validated_to_string(ctx, arguments[1], "identity"),
Value::validated_to_string(ctx, arguments[0], "authServerUrl")})) {
return_value.set(create_object<T, UserClass<T>>(ctx, new SharedUser(std::move(user))));
}
}
template<typename T>
void UserClass<T>::all_users(ContextType ctx, ObjectType object, ReturnValue &return_value) {
auto users = Object::create_empty(ctx);