mirror of
https://github.com/status-im/realm-js.git
synced 2025-01-10 14:25:58 +00:00
parent
f22efa7117
commit
bb0dc575c9
11
CHANGELOG.md
11
CHANGELOG.md
@ -1,3 +1,14 @@
|
||||
vNext Release notes (TBA)
|
||||
=============================================================
|
||||
### Breaking changes
|
||||
* None
|
||||
|
||||
### Enhancements
|
||||
* None
|
||||
|
||||
### Bug fixes
|
||||
* Proactively refresh sync user tokens to avoid a reconnect delay (#840)
|
||||
|
||||
1.0.1 Release notes (2017-2-2)
|
||||
=============================================================
|
||||
### Breaking changes
|
||||
|
@ -179,9 +179,9 @@ Object.defineProperties(Realm, {
|
||||
|
||||
for (let i = 0, len = debugHosts.length; i < len; i++) {
|
||||
try {
|
||||
let authenticateRealmCallback = staticUserMethods._authenticateRealm.bind(User);
|
||||
let refreshAccessTokenCallback = staticUserMethods._refreshAccessToken.bind(User);
|
||||
// The session ID refers to the Realm constructor object in the RPC server.
|
||||
Realm[keys.id] = rpc.createSession(authenticateRealmCallback, debugHosts[i] + ':' + debugPort);
|
||||
Realm[keys.id] = rpc.createSession(refreshAccessTokenCallback, debugHosts[i] + ':' + debugPort);
|
||||
break;
|
||||
} catch (e) {
|
||||
// Only throw exception after all hosts have been tried.
|
||||
|
@ -25,7 +25,7 @@ const {id: idKey, realm: _realmKey} = keys;
|
||||
let registeredCallbacks = [];
|
||||
const typeConverters = {};
|
||||
|
||||
// Callbacks that are registered initially (currently only authenticateRealm) will
|
||||
// Callbacks that are registered initially (currently only refreshAccessToken) will
|
||||
// carry this symbol so they are not wiped in clearTestState.
|
||||
const persistentCallback = Symbol("persistentCallback");
|
||||
|
||||
@ -49,9 +49,9 @@ export function registerTypeConverter(type, handler) {
|
||||
typeConverters[type] = handler;
|
||||
}
|
||||
|
||||
export function createSession(authenticateRealm, host) {
|
||||
authenticateRealm[persistentCallback] = true;
|
||||
sessionId = sendRequest('create_session', { authenticateRealm: serialize(undefined, authenticateRealm) }, host);
|
||||
export function createSession(refreshAccessToken, host) {
|
||||
refreshAccessToken[persistentCallback] = true;
|
||||
sessionId = sendRequest('create_session', { refreshAccessToken: serialize(undefined, refreshAccessToken) }, host);
|
||||
sessionHost = host;
|
||||
|
||||
return sessionId;
|
||||
|
@ -40,7 +40,13 @@ function auth_url(server) {
|
||||
return server + 'auth';
|
||||
}
|
||||
|
||||
function authenticateRealm(user, fileUrl, realmUrl) {
|
||||
function scheduleAccessTokenRefresh(user, localRealmPath, realmUrl, expirationDate) {
|
||||
const refreshBuffer = 10 * 1000;
|
||||
const timeout = expirationDate - Date.now() - refreshBuffer;
|
||||
setTimeout(() => refreshAccessToken(user, localRealmPath, realmUrl), timeout);
|
||||
}
|
||||
|
||||
function refreshAccessToken(user, localRealmPath, realmUrl) {
|
||||
let parsedRealmUrl = url_parse(realmUrl);
|
||||
const url = auth_url(user.server);
|
||||
const options = {
|
||||
@ -54,23 +60,36 @@ function authenticateRealm(user, fileUrl, realmUrl) {
|
||||
headers: postHeaders
|
||||
};
|
||||
performFetch(url, options)
|
||||
.then((response) => {
|
||||
// in case something lower in the HTTP stack breaks, try again in 10 seconds
|
||||
.catch(() => setTimeout(() => refreshAccessToken(user, localRealmPath, realmUrl), 10 * 1000))
|
||||
.then((response) => response.json().then((json) => { return { response, json }; }))
|
||||
.then((responseAndJson) => {
|
||||
const response = responseAndJson.response;
|
||||
const json = responseAndJson.json;
|
||||
if (response.status != 200) {
|
||||
//FIXME: propagate error to session error handler
|
||||
/*
|
||||
let session = user._sessionForOnDiskPath(localRealmPath);
|
||||
let errorHandler = session._errorHandler;
|
||||
if (errorHandler) {
|
||||
errorHandler(session, new AuthError(json));
|
||||
}
|
||||
*/
|
||||
} else {
|
||||
return response.json().then(function(body) {
|
||||
// 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
|
||||
let newUser = user.constructor.all[user.identity];
|
||||
if (newUser) {
|
||||
let session = newUser._sessionForOnDiskPath(fileUrl);
|
||||
if (session) {
|
||||
parsedRealmUrl.set('pathname', body.access_token.token_data.path);
|
||||
session._refreshAccessToken(body.access_token.token, parsedRealmUrl.href);
|
||||
}
|
||||
// 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
|
||||
let newUser = user.constructor.all[user.identity];
|
||||
if (newUser) {
|
||||
let session = newUser._sessionForOnDiskPath(localRealmPath);
|
||||
if (session && session.state !== 'invalid') {
|
||||
parsedRealmUrl.set('pathname', json.access_token.token_data.path);
|
||||
session._refreshAccessToken(json.access_token.token, parsedRealmUrl.href);
|
||||
|
||||
const tokenExpirationDate = new Date(json.access_token.token_data.expires * 1000);
|
||||
scheduleAccessTokenRefresh(newUser, localRealmPath, realmUrl, tokenExpirationDate);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -146,7 +165,7 @@ module.exports = {
|
||||
}, callback);
|
||||
},
|
||||
|
||||
_authenticateRealm: authenticateRealm
|
||||
_refreshAccessToken: refreshAccessToken
|
||||
},
|
||||
instance: {
|
||||
openManagementRealm() {
|
||||
|
@ -380,13 +380,13 @@ void SyncClass<T>::populate_sync_config(ContextType ctx, ObjectType realm_constr
|
||||
}
|
||||
else {
|
||||
ObjectType user_constructor = Object::validated_get_object(protected_ctx, protected_sync, std::string("User"));
|
||||
FunctionType authenticate = Object::validated_get_function(protected_ctx, user_constructor, std::string("_authenticateRealm"));
|
||||
FunctionType refreshAccessToken = Object::validated_get_function(protected_ctx, user_constructor, std::string("_refreshAccessToken"));
|
||||
|
||||
ValueType arguments[3];
|
||||
arguments[0] = create_object<T, UserClass<T>>(protected_ctx, new SharedUser(config.user));
|
||||
arguments[1] = Value::from_string(protected_ctx, path.c_str());
|
||||
arguments[2] = Value::from_string(protected_ctx, config.realm_url.c_str());
|
||||
Function::call(protected_ctx, authenticate, 3, arguments);
|
||||
Function::call(protected_ctx, refreshAccessToken, 3, arguments);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -113,11 +113,11 @@ RPCServer::RPCServer() {
|
||||
|
||||
jsc::String realm_string = "Realm";
|
||||
JSObjectRef realm_constructor = jsc::Object::validated_get_constructor(m_context, JSContextGetGlobalObject(m_context), realm_string);
|
||||
JSValueRef authenticateRealm = deserialize_json_value(dict["authenticateRealm"]);
|
||||
JSValueRef refreshAccessTokenCallback = deserialize_json_value(dict["refreshAccessToken"]);
|
||||
|
||||
JSObjectRef sync_constructor = (JSObjectRef)jsc::Object::get_property(m_context, realm_constructor, "Sync");
|
||||
JSObjectRef user_constructor = (JSObjectRef)jsc::Object::get_property(m_context, sync_constructor, "User");
|
||||
jsc::Object::set_property(m_context, user_constructor, "_authenticateRealm", authenticateRealm);
|
||||
jsc::Object::set_property(m_context, user_constructor, "_refreshAccessToken", refreshAccessTokenCallback);
|
||||
|
||||
m_session_id = store_object(realm_constructor);
|
||||
return (json){{"result", m_session_id}};
|
||||
|
Loading…
x
Reference in New Issue
Block a user