mirror of https://github.com/laurent22/joplin.git
All: Improved workflow of downloading and decrypting data during sync
parent
3ba021fdd9
commit
316a52bbc2
|
@ -448,7 +448,7 @@ class MainScreenComponent extends React.Component {
|
||||||
if (this.props.hasDisabledSyncItems) {
|
if (this.props.hasDisabledSyncItems) {
|
||||||
msg = <span>{_('Some items cannot be synchronised.')} <a href="#" onClick={() => { onViewDisabledItemsClick() }}>{_('View them now')}</a></span>
|
msg = <span>{_('Some items cannot be synchronised.')} <a href="#" onClick={() => { onViewDisabledItemsClick() }}>{_('View them now')}</a></span>
|
||||||
} else if (this.props.showMissingMasterKeyMessage) {
|
} else if (this.props.showMissingMasterKeyMessage) {
|
||||||
msg = <span>{_('Some items cannot be decrypted.')} <a href="#" onClick={() => { onViewMasterKeysClick() }}>{_('Set the password')}</a></span>
|
msg = <span>{_('One or more master keys need a password.')} <a href="#" onClick={() => { onViewMasterKeysClick() }}>{_('Set the password')}</a></span>
|
||||||
}
|
}
|
||||||
|
|
||||||
messageComp = (
|
messageComp = (
|
||||||
|
|
|
@ -59,6 +59,8 @@ class BaseApplication {
|
||||||
// be derived from the state and not set directly since that would make the
|
// be derived from the state and not set directly since that would make the
|
||||||
// state and UI out of sync.
|
// state and UI out of sync.
|
||||||
this.currentFolder_ = null;
|
this.currentFolder_ = null;
|
||||||
|
|
||||||
|
this.decryptionWorker_resourceMetadataButNotBlobDecrypted = this.decryptionWorker_resourceMetadataButNotBlobDecrypted.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
logger() {
|
logger() {
|
||||||
|
@ -285,6 +287,19 @@ class BaseApplication {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async decryptionWorker_resourceMetadataButNotBlobDecrypted(event) {
|
||||||
|
this.scheduleAutoAddResources();
|
||||||
|
}
|
||||||
|
|
||||||
|
scheduleAutoAddResources() {
|
||||||
|
if (this.scheduleAutoAddResourcesIID_) return;
|
||||||
|
|
||||||
|
this.scheduleAutoAddResourcesIID_ = setTimeout(() => {
|
||||||
|
this.scheduleAutoAddResourcesIID_ = null;
|
||||||
|
ResourceFetcher.instance().autoAddResources();
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
reducerActionToString(action) {
|
reducerActionToString(action) {
|
||||||
let o = [action.type];
|
let o = [action.type];
|
||||||
if ('id' in action) o.push(action.id);
|
if ('id' in action) o.push(action.id);
|
||||||
|
@ -314,7 +329,7 @@ class BaseApplication {
|
||||||
}
|
}
|
||||||
|
|
||||||
async generalMiddleware(store, next, action) {
|
async generalMiddleware(store, next, action) {
|
||||||
this.logger().debug('Reducer action', this.reducerActionToString(action));
|
// this.logger().debug('Reducer action', this.reducerActionToString(action));
|
||||||
|
|
||||||
const result = next(action);
|
const result = next(action);
|
||||||
const newState = store.getState();
|
const newState = store.getState();
|
||||||
|
@ -608,6 +623,7 @@ class BaseApplication {
|
||||||
DecryptionWorker.instance().setLogger(this.logger_);
|
DecryptionWorker.instance().setLogger(this.logger_);
|
||||||
DecryptionWorker.instance().setEncryptionService(EncryptionService.instance());
|
DecryptionWorker.instance().setEncryptionService(EncryptionService.instance());
|
||||||
await EncryptionService.instance().loadMasterKeysFromSettings();
|
await EncryptionService.instance().loadMasterKeysFromSettings();
|
||||||
|
DecryptionWorker.instance().on('resourceMetadataButNotBlobDecrypted', this.decryptionWorker_resourceMetadataButNotBlobDecrypted);
|
||||||
|
|
||||||
ResourceFetcher.instance().setFileApi(() => { return reg.syncTarget().fileApi() });
|
ResourceFetcher.instance().setFileApi(() => { return reg.syncTarget().fileApi() });
|
||||||
ResourceFetcher.instance().setLogger(this.logger_);
|
ResourceFetcher.instance().setLogger(this.logger_);
|
||||||
|
|
|
@ -535,6 +535,12 @@ const reducer = (state = defaultState, action) => {
|
||||||
newState.masterKeys = action.items;
|
newState.masterKeys = action.items;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'MASTERKEY_SET_NOT_LOADED':
|
||||||
|
|
||||||
|
newState = Object.assign({}, state);
|
||||||
|
newState.notLoadedMasterKeys = action.ids;
|
||||||
|
break;
|
||||||
|
|
||||||
case 'MASTERKEY_ADD_NOT_LOADED':
|
case 'MASTERKEY_ADD_NOT_LOADED':
|
||||||
|
|
||||||
if (state.notLoadedMasterKeys.indexOf(action.id) < 0) {
|
if (state.notLoadedMasterKeys.indexOf(action.id) < 0) {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
const BaseItem = require('lib/models/BaseItem');
|
const BaseItem = require('lib/models/BaseItem');
|
||||||
|
const MasterKey = require('lib/models/MasterKey');
|
||||||
const Resource = require('lib/models/Resource');
|
const Resource = require('lib/models/Resource');
|
||||||
const ResourceService = require('lib/services/ResourceService');
|
const ResourceService = require('lib/services/ResourceService');
|
||||||
const { Logger } = require('lib/logger.js');
|
const { Logger } = require('lib/logger.js');
|
||||||
|
@ -75,6 +76,20 @@ class DecryptionWorker {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const loadedMasterKeyCount = await this.encryptionService().loadedMasterKeysCount();
|
||||||
|
if (!loadedMasterKeyCount) {
|
||||||
|
this.logger().info('DecryptionWorker: cannot start because no master key is currently loaded.');
|
||||||
|
const ids = await MasterKey.allIds();
|
||||||
|
|
||||||
|
if (ids.length) {
|
||||||
|
this.dispatch({
|
||||||
|
type: 'MASTERKEY_SET_NOT_LOADED',
|
||||||
|
ids: ids,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.logger().info('DecryptionWorker: starting decryption...');
|
this.logger().info('DecryptionWorker: starting decryption...');
|
||||||
|
|
||||||
this.state_ = 'started';
|
this.state_ = 'started';
|
||||||
|
@ -101,7 +116,7 @@ class DecryptionWorker {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Don't log in production as it results in many messages when importing many items
|
// Don't log in production as it results in many messages when importing many items
|
||||||
// this.logger().info('DecryptionWorker: decrypting: ' + item.id + ' (' + ItemClass.tableName() + ')');
|
// this.logger().debug('DecryptionWorker: decrypting: ' + item.id + ' (' + ItemClass.tableName() + ')');
|
||||||
try {
|
try {
|
||||||
const decryptedItem = await ItemClass.decrypt(item);
|
const decryptedItem = await ItemClass.decrypt(item);
|
||||||
|
|
||||||
|
@ -115,6 +130,10 @@ class DecryptionWorker {
|
||||||
if (decryptedItem.type_ === Resource.modelType() && !decryptedItem.encryption_blob_encrypted) {
|
if (decryptedItem.type_ === Resource.modelType() && !decryptedItem.encryption_blob_encrypted) {
|
||||||
this.eventEmitter_.emit('resourceDecrypted', { id: decryptedItem.id });
|
this.eventEmitter_.emit('resourceDecrypted', { id: decryptedItem.id });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (decryptedItem.type_ === Resource.modelType() && !decryptedItem.encryption_applied && !!decryptedItem.encryption_blob_encrypted) {
|
||||||
|
this.eventEmitter_.emit('resourceMetadataButNotBlobDecrypted', { id: decryptedItem.id });
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
excludedIds.push(item.id);
|
excludedIds.push(item.id);
|
||||||
|
|
||||||
|
@ -154,10 +173,10 @@ class DecryptionWorker {
|
||||||
|
|
||||||
const downloadedButEncryptedBlobCount = await Resource.downloadedButEncryptedBlobCount();
|
const downloadedButEncryptedBlobCount = await Resource.downloadedButEncryptedBlobCount();
|
||||||
|
|
||||||
this.dispatchReport({ state: 'idle' });
|
|
||||||
|
|
||||||
this.state_ = 'idle';
|
this.state_ = 'idle';
|
||||||
|
|
||||||
|
this.dispatchReport({ state: 'idle' });
|
||||||
|
|
||||||
if (downloadedButEncryptedBlobCount) {
|
if (downloadedButEncryptedBlobCount) {
|
||||||
this.logger().info('DecryptionWorker: Some resources have been downloaded but are not decrypted yet. Scheduling another decryption. Resource count: ' + downloadedButEncryptedBlobCount);
|
this.logger().info('DecryptionWorker: Some resources have been downloaded but are not decrypted yet. Scheduling another decryption. Resource count: ' + downloadedButEncryptedBlobCount);
|
||||||
this.scheduleStart();
|
this.scheduleStart();
|
||||||
|
|
|
@ -120,6 +120,7 @@ class ResourceFetcher extends BaseService {
|
||||||
// sync. The other ones have been done using migrations/20.js. This code can be removed
|
// sync. The other ones have been done using migrations/20.js. This code can be removed
|
||||||
// after a few months.
|
// after a few months.
|
||||||
if (resource && resource.size < 0 && localResourceContentPath && !resource.encryption_blob_encrypted) {
|
if (resource && resource.size < 0 && localResourceContentPath && !resource.encryption_blob_encrypted) {
|
||||||
|
await shim.fsDriver().waitTillExists(localResourceContentPath);
|
||||||
await ResourceService.autoSetFileSizes();
|
await ResourceService.autoSetFileSizes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,7 +195,9 @@ class ResourceFetcher extends BaseService {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async autoAddResources(limit) {
|
async autoAddResources(limit = null) {
|
||||||
|
if (limit === null) limit = 10;
|
||||||
|
|
||||||
if (this.addingResources_) return;
|
if (this.addingResources_) return;
|
||||||
this.addingResources_ = true;
|
this.addingResources_ = true;
|
||||||
|
|
||||||
|
|
|
@ -111,8 +111,8 @@ class ResourceService extends BaseService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static async autoSetFileSize(resourceId, filePath) {
|
static async autoSetFileSize(resourceId, filePath, waitTillExists = true) {
|
||||||
const itDoes = await shim.fsDriver().waitTillExists(filePath);
|
const itDoes = await shim.fsDriver().waitTillExists(filePath, waitTillExists ? 10000 : 0);
|
||||||
if (!itDoes) {
|
if (!itDoes) {
|
||||||
// this.logger().warn('Trying to set file size on non-existent resource:', resourceId, filePath);
|
// this.logger().warn('Trying to set file size on non-existent resource:', resourceId, filePath);
|
||||||
return;
|
return;
|
||||||
|
@ -125,7 +125,7 @@ class ResourceService extends BaseService {
|
||||||
const resources = await Resource.needFileSizeSet();
|
const resources = await Resource.needFileSizeSet();
|
||||||
|
|
||||||
for (const r of resources) {
|
for (const r of resources) {
|
||||||
await this.autoSetFileSize(r.id, Resource.fullPath(r));
|
await this.autoSetFileSize(r.id, Resource.fullPath(r), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,7 @@ const logReducerAction = function(action) {
|
||||||
let msg = [action.type];
|
let msg = [action.type];
|
||||||
if (action.routeName) msg.push(action.routeName);
|
if (action.routeName) msg.push(action.routeName);
|
||||||
|
|
||||||
reg.logger().info('Reducer action', msg.join(', '));
|
// reg.logger().debug('Reducer action', msg.join(', '));
|
||||||
}
|
}
|
||||||
|
|
||||||
const generalMiddleware = store => next => async (action) => {
|
const generalMiddleware = store => next => async (action) => {
|
||||||
|
|
Loading…
Reference in New Issue