1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-24 10:27:10 +02:00

All: Fixed issue with local resource needlessly marked as encrypted

This commit is contained in:
Laurent Cozic 2017-12-04 19:01:56 +00:00
parent f9634ea283
commit 685f541bb4
4 changed files with 45 additions and 8 deletions

View File

@ -948,4 +948,19 @@ describe('Synchronizer', function() {
expect(await allSyncTargetItemsEncrypted()).toBe(true);
}));
it('should upload encrypted resource, but it should not mark the blob as encrypted locally', asyncTest(async () => {
while (insideBeforeEach) await time.msleep(100);
let folder1 = await Folder.save({ title: "folder1" });
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
await shim.attachFileToNote(note1, __dirname + '/../tests/support/photo.jpg');
const masterKey = await loadEncryptionMasterKey();
await encryptionService().enableEncryption(masterKey, '123456');
await encryptionService().loadMasterKeysFromSettings();
await synchronizer().start();
let resource1 = (await Resource.all())[0];
expect(resource1.encryption_blob_encrypted).toBe(0);
}));
});

View File

@ -76,10 +76,11 @@ class Resource extends BaseItem {
return super.save(decryptedItem, { autoTimestamp: false });
}
// Prepare the resource by encrypting it if needed.
// The call returns the path to the physical file AND the resource object
// which may have been modified. So the caller should update their copy with this.
// The call returns the path to the physical file AND a representation of the resource object
// as it should be uploaded to the sync target. Note that this may be different from what is stored
// in the database. In particular, the flag encryption_blob_encrypted might be 1 on the sync target
// if the resource is encrypted, but will be 0 locally because the device has the decrypted resource.
static async fullPathForSyncUpload(resource) {
const plainTextPath = this.fullPath(resource);
@ -93,10 +94,9 @@ class Resource extends BaseItem {
if (resource.encryption_blob_encrypted) return { path: encryptedPath, resource: resource };
await this.encryptionService().encryptFile(plainTextPath, encryptedPath);
resource.encryption_blob_encrypted = 1;
await Resource.save(resource, { autoTimestamp: false });
return { path: encryptedPath, resource: resource };
const resourceCopy = Object.assign({}, resource);
resourceCopy.encryption_blob_encrypted = 1;
return { path: encryptedPath, resource: resourceCopy };
}
static markdownTag(resource) {

View File

@ -70,8 +70,8 @@ class DecryptionWorker {
for (let i = 0; i < items.length; i++) {
const item = items[i];
this.logger().debug('DecryptionWorker: decrypting: ' + item.id);
const ItemClass = BaseItem.itemClass(item);
this.logger().debug('DecryptionWorker: decrypting: ' + item.id + ' (' + ItemClass.tableName() + ')');
try {
await ItemClass.decrypt(item);
} catch (error) {

View File

@ -322,7 +322,10 @@ class EncryptionService {
async decryptAbstract_(source, destination) {
const identifier = await source.read(5);
if (!this.isValidHeaderIdentifier(identifier)) throw new Error('Invalid encryption identifier. Data is not actually encrypted? ID was: ' + identifier);
const mdSizeHex = await source.read(6);
const mdSize = parseInt(mdSizeHex, 16);
if (isNaN(mdSize) || !mdSize) throw new Error('Invalid header metadata size: ' + mdSizeHex);
const md = await source.read(parseInt(mdSizeHex, 16));
const header = this.decodeHeader_(identifier + mdSizeHex + md);
const masterKeyPlainText = this.loadedMasterKey(header.masterKeyId);
@ -503,6 +506,25 @@ class EncryptionService {
return output;
}
isValidHeaderIdentifier(id, ignoreTooLongLength = false) {
if (!ignoreTooLongLength && !id || id.length !== 5) return false;
return /JED\d\d/.test(id);
}
async itemIsEncrypted(item) {
if (!item) throw new Error('No item');
const ItemClass = BaseItem.itemClass(item);
if (!ItemClass.encryptionSupported()) return false;
return item.encryption_applied && this.isValidHeaderIdentifier(item.encryption_cipher_text);
}
async fileIsEncrypted(path) {
const handle = await this.fsDriver().open(path, 'r');
const headerIdentifier = await this.fsDriver().readFileChunk(handle, 5, 'ascii');
await this.fsDriver().close(handle);
return this.isValidHeaderIdentifier(headerIdentifier);
}
}
EncryptionService.METHOD_SJCL = 1;